├── src ├── prismic.starter │ ├── Views │ │ ├── _ViewStart.cshtml │ │ ├── Shared │ │ │ ├── Error.cshtml │ │ │ └── _Layout.cshtml │ │ ├── Home │ │ │ ├── Detail.cshtml │ │ │ ├── PageNotFound.cshtml │ │ │ ├── Toolbar.cshtml │ │ │ ├── Search.cshtml │ │ │ └── Index.cshtml │ │ └── Web.config │ ├── favicon.ico │ ├── Global.asax │ ├── Scripts │ │ ├── _references.js │ │ ├── respond.min.js │ │ ├── jquery.validate.unobtrusive.min.js │ │ ├── respond.js │ │ ├── jquery.validate.unobtrusive.js │ │ ├── jquery.validate.min.js │ │ ├── bootstrap.min.js │ │ └── jquery.validate.js │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.ttf │ │ └── glyphicons-halflings-regular.woff │ ├── App_Start │ │ ├── FilterConfig.cs │ │ ├── RouteConfig.cs │ │ └── BundleConfig.cs │ ├── Controllers │ │ ├── PrismicLogger.cs │ │ └── HomeController.cs │ ├── Content │ │ └── Site.css │ ├── Filters │ │ ├── PrismicLinkResolver.cs │ │ └── PrismicApiHome.cs │ ├── Helpers.cs │ ├── Models │ │ ├── PrismicContext.cs │ │ └── PrismicViewModel.cs │ ├── prismic.starter.csproj.user │ ├── Global.asax.cs │ ├── packages.config │ ├── Web.Debug.config │ ├── Web.Release.config │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── web.config │ ├── Project_Readme.html │ └── prismic.starter.csproj ├── prismic.starter.v12.suo └── prismic.starter.sln ├── ReleaseNotes.md ├── .gitignore └── README.md /src/prismic.starter/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/_Layout.cshtml"; 3 | } 4 | -------------------------------------------------------------------------------- /ReleaseNotes.md: -------------------------------------------------------------------------------- 1 | ### New in 1.0.0 (Released 2014/05/30) 2 | * Initial version: starter kit for ASP.NET MVC 3 | -------------------------------------------------------------------------------- /src/prismic.starter.v12.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prismicio/dotnet-starter-kit/master/src/prismic.starter.v12.suo -------------------------------------------------------------------------------- /src/prismic.starter/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prismicio/dotnet-starter-kit/master/src/prismic.starter/favicon.ico -------------------------------------------------------------------------------- /src/prismic.starter/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="prismic.starter.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /src/prismic.starter/Scripts/_references.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prismicio/dotnet-starter-kit/master/src/prismic.starter/Scripts/_references.js -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # dlls 2 | [Oo]bj/ 3 | [Bb]in 4 | [Dd]ebug*/ 5 | [Rr]elease*/ 6 | 7 | src/packages/ 8 | 9 | #MonoDevelop 10 | *.pidb 11 | *.userprefs 12 | -------------------------------------------------------------------------------- /src/prismic.starter/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model System.Web.Mvc.HandleErrorInfo 2 | 3 |
4 |

An error occurred while processing your request.

5 |
6 | 7 | -------------------------------------------------------------------------------- /src/prismic.starter/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prismicio/dotnet-starter-kit/master/src/prismic.starter/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /src/prismic.starter/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prismicio/dotnet-starter-kit/master/src/prismic.starter/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /src/prismic.starter/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prismicio/dotnet-starter-kit/master/src/prismic.starter/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /src/prismic.starter/Views/Home/Detail.cshtml: -------------------------------------------------------------------------------- 1 | @using prismic 2 | @model prismic.mvc.starter.PrismicDocument 3 | 4 |
5 | @Html.Raw(Model.DocumentAsHtml) 6 |
7 | 8 | -------------------------------------------------------------------------------- /src/prismic.starter/App_Start/FilterConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Mvc; 3 | 4 | namespace prismic.starter 5 | { 6 | public class FilterConfig 7 | { 8 | public static void RegisterGlobalFilters(GlobalFilterCollection filters) 9 | { 10 | filters.Add(new HandleErrorAttribute()); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/prismic.starter/Controllers/PrismicLogger.cs: -------------------------------------------------------------------------------- 1 | 2 | using System; 3 | using prismic; 4 | 5 | namespace prismic.mvc.starter 6 | { 7 | public class PrismicLogger: ILogger 8 | { 9 | public PrismicLogger () 10 | { 11 | } 12 | 13 | public void log(string level, string message) { 14 | System.Diagnostics.Debug.WriteLine(level + ": " + message); 15 | } 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /src/prismic.starter/Views/Home/PageNotFound.cshtml: -------------------------------------------------------------------------------- 1 | @using prismic 2 | @model prismic.mvc.starter.PrismicViewModel 3 | 4 |
5 |

Page not found

6 |
7 | 8 |
9 |

10 | We can't seem to find what you are looking for. 11 |

12 | 13 |

14 | @Html.ActionLink("Go to the home page", "Index", new { refId = Model.Context.MaybeRef }) 15 |

16 |
17 | -------------------------------------------------------------------------------- /src/prismic.starter/Content/Site.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | padding-bottom: 20px; 4 | } 5 | 6 | /* Set padding to keep content from hitting the edges */ 7 | .body-content { 8 | padding-left: 15px; 9 | padding-right: 15px; 10 | } 11 | 12 | /* Override the default bootstrap behavior where horizontal description lists 13 | will truncate terms that are too long to fit in the left column 14 | */ 15 | .dl-horizontal dt { 16 | white-space: normal; 17 | } 18 | 19 | /* Set width on the form input elements since they're 100% wide by default */ 20 | input, 21 | select, 22 | textarea { 23 | max-width: 280px; 24 | } 25 | -------------------------------------------------------------------------------- /src/prismic.starter/Filters/PrismicLinkResolver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Web.Mvc; 4 | using System.Web.Routing; 5 | using prismic; 6 | 7 | namespace prismic.mvc.starter 8 | { 9 | public static class PrismicLinkResolver 10 | { 11 | public static DocumentLinkResolver Get(Api api, string maybeRef, RequestContext requestContext) 12 | { 13 | return prismic.DocumentLinkResolver.For ( 14 | (documentLink) => 15 | !documentLink.IsBroken 16 | ? requestContext.RouteUrlFor("Detail", "Home", new { documentLink.Id, documentLink.Slug }) 17 | : requestContext.RouteUrlFor("BrokenLink", "Home", new {}) 18 | ); 19 | } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /src/prismic.starter/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 prismic.starter 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 | ); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/prismic.starter/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | @using prismic 2 | @model prismic.mvc.starter.PrismicViewModel 3 | @{string refId = Model.Context.MaybeRef;} 4 | @{string endpoint = Model.Context.Endpoint;} 5 | 6 | 7 | 8 | 9 | @ViewBag.Title 10 | @Scripts.Render("~/bundles/jquery") 11 | @Scripts.Render("~/bundles/bootstrap") 12 | @Styles.Render("~/Content/css") 13 | 14 | @** Required for Previews and Experiments *@ 15 | 20 | 21 | 22 | 23 |
24 |

@Html.ActionLink("Your prismic.io project", "Index", new { refId })

25 |
26 | @RenderBody() 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/prismic.starter/Filters/PrismicApiHome.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web.Configuration; 3 | using System.Diagnostics.Contracts; 4 | using System.Threading.Tasks; 5 | 6 | namespace prismic.mvc.starter 7 | { 8 | 9 | /// 10 | /// Prismic API home is the entry point for the prismic.io API 11 | /// that sets the caching and logging strategies 12 | /// 13 | public class PrismicApiHome 14 | { 15 | 16 | readonly string apiUrl; 17 | 18 | public PrismicApiHome(string apiUrl) 19 | { 20 | Contract.Assert (!string.IsNullOrEmpty (apiUrl)); 21 | this.apiUrl = apiUrl; 22 | } 23 | 24 | public async Task Get(string accessToken) 25 | { 26 | return await prismic.Api.Get (this.apiUrl, accessToken, new prismic.DefaultCache(), new PrismicLogger()); 27 | } 28 | public async Task Get() 29 | { 30 | var accessToken = WebConfigurationManager.AppSettings["prismic.token"]; 31 | return await this.Get (accessToken); 32 | } 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/prismic.starter/Helpers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections.Generic; 4 | using System.Collections.Specialized; 5 | using System.Net; 6 | using System.Text; 7 | using System.Web; 8 | using System.Web.Mvc; 9 | using System.Web.Routing; 10 | using prismic; 11 | 12 | namespace prismic.mvc.starter 13 | { 14 | 15 | public static class RequestContextExt 16 | { 17 | private static RouteValueDictionary Extend(this RouteValueDictionary dest, IEnumerable> src) 18 | { 19 | src.ToList().ForEach(x => { dest[x.Key] = x.Value; }); 20 | return dest; 21 | } 22 | 23 | public static string RouteUrlFor(this RequestContext requestContext, string action, string controller, object routeValues) 24 | { 25 | var values = 26 | new RouteValueDictionary {{"action", action}, {"controller", controller}} 27 | .Extend (new RouteValueDictionary(routeValues)); 28 | 29 | var helper = new UrlHelper(requestContext); 30 | return helper.RouteUrl (values); 31 | } 32 | 33 | } 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/prismic.starter.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "prismic.starter", "prismic.starter\prismic.starter.csproj", "{E77D4793-5695-493C-913E-02115684B86A}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {E77D4793-5695-493C-913E-02115684B86A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {E77D4793-5695-493C-913E-02115684B86A}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {E77D4793-5695-493C-913E-02115684B86A}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {E77D4793-5695-493C-913E-02115684B86A}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /src/prismic.starter/Models/PrismicContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections.Generic; 4 | using prismic; 5 | 6 | namespace prismic.mvc.starter 7 | { 8 | public class PrismicContext 9 | { 10 | readonly prismic.Api api; 11 | readonly string endpoint; 12 | readonly string maybeRef; 13 | readonly prismic.DocumentLinkResolver linkResolver; 14 | 15 | public PrismicContext(){} 16 | 17 | public PrismicContext(string endpoint, prismic.Api api, string maybeRef, prismic.DocumentLinkResolver linkResolver) 18 | { 19 | this.endpoint = endpoint; 20 | this.api = api; 21 | this.maybeRef = maybeRef; 22 | this.linkResolver = linkResolver; 23 | } 24 | public prismic.Api Api { get { return this.api; } } 25 | public string Endpoint { get { return this.endpoint; } } 26 | public string MaybeRef { get { return this.maybeRef; } } 27 | 28 | public prismic.DocumentLinkResolver LinkResolver 29 | { 30 | get { return this.linkResolver; } 31 | } 32 | 33 | public string ResolveLink(prismic.Document document) 34 | { 35 | return this.linkResolver.Resolve (document); 36 | } 37 | 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/prismic.starter/prismic.starter.csproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | CurrentPage 10 | True 11 | False 12 | False 13 | False 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | True 23 | True 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/prismic.starter/Views/Home/Toolbar.cshtml: -------------------------------------------------------------------------------- 1 | @using prismic.extensions 2 | @model prismic.mvc.starter.PrismicViewModel 3 | @{string refId = Model.Context.MaybeRef.GetOrElse(null);} 4 | 5 | @if(Model.Context.HasPrivilegedAccess) { 6 |
7 | 8 |
9 | 10 | 22 |
23 | 24 | @using (Html.BeginForm("Signout", "Home", null, FormMethod.Post )){ 25 | 26 | } 27 |
28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/prismic.starter/Global.asax.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.Optimization; 7 | using System.Web.Routing; 8 | 9 | namespace prismic.starter 10 | { 11 | public class MvcApplication : System.Web.HttpApplication 12 | { 13 | public static void RegisterRoutes(RouteCollection routes) 14 | { 15 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 16 | 17 | routes.MapRoute( 18 | "Default", 19 | "{controller}/{action}/{id}", 20 | new { controller = "Home", action = "Index", id = "" } 21 | ); 22 | 23 | } 24 | 25 | public static void RegisterGlobalFilters(GlobalFilterCollection filters) 26 | { 27 | filters.Add(new HandleErrorAttribute()); 28 | } 29 | 30 | protected void Application_Start() 31 | { 32 | AreaRegistration.RegisterAllAreas(); 33 | FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 34 | RouteConfig.RegisterRoutes(RouteTable.Routes); 35 | BundleConfig.RegisterBundles(BundleTable.Bundles); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/prismic.starter/Views/Home/Search.cshtml: -------------------------------------------------------------------------------- 1 | @using prismic 2 | @model prismic.mvc.starter.PrismicSearchResponse 3 | @{string refId = Model.Context.MaybeRef;} 4 | 5 |

6 | @switch (Model.Response.Results.Count) 7 | { 8 | case 0: @:No documents found 9 | break; 10 | case 1: @:One document found 11 | break; 12 | default: @:Showing @Model.Response.Results.Count out of @Model.Response.TotalResultsSize documents 13 | break; 14 | } 15 |

16 |
    17 | @foreach (var document in Model.Response.Results) { 18 |
  • 19 | @document.Slug 20 |
  • 21 | } 22 |
23 | 24 | @if(Model.Response.TotalPages > 1) { 25 |
26 | @if(Model.Response.PrevPage != null) { 27 | @Html.ActionLink("Previous", "Index", new { q = Model.Query, refId, page = Model.Response.Page - 1 }) 28 | } else { 29 | Previous 30 | } 31 | @if(Model.Response.NextPage != null) { 32 | @Html.ActionLink("Next", "Index", new { q = Model.Query, refId, page = Model.Response.Page + 1 }) 33 | } else { 34 | Next 35 | } 36 |
37 | } 38 | 39 |

40 | @Html.ActionLink("Back to home", "Index", new { refId }) 41 |

-------------------------------------------------------------------------------- /src/prismic.starter/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/prismic.starter/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @using prismic 2 | @model prismic.mvc.starter.PrismicResponse 3 | @{string refId = Model.Context.MaybeRef;} 4 | 5 | @using (Html.BeginForm("Search", "Home", new { refId }, FormMethod.Post )){ 6 | @Html.TextBox("q") 7 | 8 | } 9 |
10 | 11 |

12 | @switch (Model.Response.Results.Count) 13 | { 14 | case 0: @:No documents found 15 | break; 16 | case 1: @:One document found 17 | break; 18 | default: @:Showing @Model.Response.Results.Count out of @Model.Response.TotalResultsSize documents 19 | break; 20 | } 21 |

22 |
    23 | @foreach (var document in Model.Response.Results) { 24 |
  • 25 | @Html.ActionLink(document.Slug, "Detail", new { document.Id, slug = document.Slug, refId }) 26 |
  • 27 | } 28 |
29 | 30 | 31 | @if(Model.Response.TotalPages > 1) { 32 |
33 | @if(Model.Response.PrevPage != null) { 34 | @Html.ActionLink("Previous", "Index", new { refId, page = Model.Response.Page - 1 }) 35 | } else { 36 | Previous 37 | } 38 | @if(Model.Response.NextPage != null) { 39 | @Html.ActionLink("Next", "Index", new { refId, page = Model.Response.Page + 1 }) 40 | } else { 41 | Next 42 | } 43 |
44 | } -------------------------------------------------------------------------------- /src/prismic.starter/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/prismic.starter/App_Start/BundleConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Optimization; 3 | 4 | namespace prismic.starter 5 | { 6 | public class BundleConfig 7 | { 8 | // For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862 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/jqueryval").Include( 15 | "~/Scripts/jquery.validate*")); 16 | 17 | // Use the development version of Modernizr to develop with and learn from. Then, when you're 18 | // ready for production, use the build tool at http://modernizr.com to pick only the tests you need. 19 | bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( 20 | "~/Scripts/modernizr-*")); 21 | 22 | bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( 23 | "~/Scripts/bootstrap.js", 24 | "~/Scripts/respond.js")); 25 | 26 | bundles.Add(new StyleBundle("~/Content/css").Include( 27 | "~/Content/bootstrap.css", 28 | "~/Content/site.css")); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/prismic.starter/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/prismic.starter/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("prismic.starter")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("prismic.starter")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 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("e4017691-9b44-41a6-babb-21be1d61bc12")] 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 | -------------------------------------------------------------------------------- /src/prismic.starter/Models/PrismicViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using prismic; 3 | 4 | namespace prismic.mvc.starter 5 | { 6 | public class PrismicViewModel 7 | { 8 | readonly PrismicContext ctx; 9 | public PrismicViewModel(PrismicContext ctx) 10 | { 11 | this.ctx = ctx; 12 | } 13 | public PrismicContext Context 14 | { 15 | get { return this.ctx; } 16 | } 17 | } 18 | 19 | public class PrismicSearchResponse : PrismicViewModel 20 | { 21 | readonly prismic.Response response; 22 | readonly string q; 23 | 24 | public PrismicSearchResponse(PrismicContext ctx, prismic.Response response, string q) : base(ctx) 25 | { 26 | this.q = q; 27 | this.response = response; 28 | } 29 | public prismic.Response Response { get { return this.response; } } 30 | public string Query { get { return this.q; } } 31 | } 32 | 33 | public class PrismicResponse : PrismicViewModel 34 | { 35 | readonly prismic.Response response; 36 | public PrismicResponse(PrismicContext ctx, prismic.Response response) : base(ctx) 37 | { 38 | this.response = response; 39 | } 40 | public prismic.Response Response { get { return this.response; } } 41 | } 42 | 43 | public class PrismicDocument : PrismicViewModel 44 | { 45 | readonly prismic.Document document; 46 | public PrismicDocument(PrismicContext ctx, prismic.Document document) : base(ctx) 47 | { 48 | this.document = document; 49 | } 50 | public prismic.Document Document { get { return this.document; } } 51 | 52 | public string DocumentAsHtml 53 | { 54 | get { 55 | return this.document.AsHtml (Context.LinkResolver); 56 | } 57 | } 58 | } 59 | } 60 | 61 | -------------------------------------------------------------------------------- /src/prismic.starter/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 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/prismic.starter/web.config: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## .NET starter project for prismic.io 2 | 3 | This is a blank ASP.NET MVC project that will connect to any prismic.io repository, and trivially list its documents. It uses the prismic.io .NET development kit, and provides a few helpers to integrate with ASP.NET MVC. 4 | 5 | ### Getting started 6 | 7 | #### Launch the starter project 8 | 9 | Fork this repository, then clone your fork, and launch the server like for any ASP.NET MVC project. 10 | 11 | Your ASP.NET MVC starter project is now up and running! However, by default, it will list and display documents from our "[Les Bonnes Choses](http://lesbonneschoses.prismic.me)" example repository. 12 | 13 | *(Feel free to detail the proper steps for beginners by [submitting a pull request](https://developers.prismic.io/documentation/UszOeAEAANUlwFpp/contribute-to-the-official-kits).)* 14 | 15 | #### Configure the starter project 16 | 17 | Change the ```https://lesbonneschoses.prismic.io/api``` API endpoint in the configuration file into your repository's endpoint. 18 | 19 | To set up the OAuth configuration and interactive signin, go to the _Applications_ panel in your repository's settings, and create a new OAuth application. You simply have to fill in an application name and potentially the callback URL (`localhost` URLs are always authorized, so at development time you can omit to fill in the Callback URL field). After submitting, copy/paste the `clientId` & `clientSecret` tokens into the proper place in your configuration. 20 | 21 | You may have to restart your ASP.NET MVC server. 22 | 23 | #### Get started with prismic.io 24 | 25 | You can find out [how to get started with prismic.io](https://developers.prismic.io/documentation/UjBaQsuvzdIHvE4D/getting-started) on our [prismic.io developer's portal](https://developers.prismic.io/). 26 | 27 | #### Understand the .NET development kit 28 | 29 | You'll find more information about how to use the development kit included in this starter project, by reading [its README file](https://github.com/prismicio/dotnet-kit). 30 | 31 | ### Contribute to the starter project 32 | 33 | Contribution is open to all developer levels, read our "[Contribute to the official kits](https://developers.prismic.io/documentation/UszOeAEAANUlwFpp/contribute-to-the-official-kits)" documentation to learn more. 34 | 35 | 36 | ### Licence 37 | 38 | This software is licensed under the Apache 2 license, quoted below. 39 | 40 | Copyright 2013 Zengularity (http://www.zengularity.com). 41 | 42 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 43 | 44 | Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 45 | -------------------------------------------------------------------------------- /src/prismic.starter/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Web; 4 | using System.Web.Configuration; 5 | using System.Web.Mvc; 6 | using prismic.mvc.starter; 7 | using System.Threading.Tasks; 8 | 9 | namespace prismic.mvc.starter.Controllers 10 | { 11 | public class HomeController : Controller 12 | { 13 | public async Task Index (int page = 1) 14 | { 15 | var ctx = await getContext(); 16 | var response = await ctx.Api.Form("everything").Ref (ctx.MaybeRef).PageSize (10).Page (page).Submit (); 17 | ViewBag.Title = "All documents"; 18 | var model = new PrismicResponse(ctx, response); 19 | return View (model); 20 | } 21 | 22 | public async Task Detail(string id, string slug) 23 | { 24 | var ctx = await getContext(); 25 | var response = await ctx.Api.Form("everything") 26 | .Query(Predicates.at("document.id", id)) 27 | .Ref (ctx.MaybeRef) 28 | .Submit (); 29 | 30 | var document = response.Results.FirstOrDefault (); 31 | if (document != null && document.Slug == slug) { 32 | ViewBag.Title = "Document detail " + slug; 33 | return View (new PrismicDocument (ctx, document)); 34 | } 35 | else if (document != null && document.Slugs.Contains(slug)) { 36 | return RedirectToActionPermanent ("Detail", new { id, document.Slug }); 37 | } else { 38 | ViewBag.Title = "Document not found"; 39 | this.Response.StatusCode = 404; 40 | return View ("PageNotFound", new PrismicViewModel(ctx)); 41 | } 42 | } 43 | 44 | public ActionResult BrokenLink() 45 | { 46 | return RedirectToAction ("PageNotFound"); 47 | } 48 | 49 | public async Task PageNotFound() 50 | { 51 | var ctx = await getContext(); 52 | ViewBag.Title = "Document not found"; 53 | return View (new PrismicViewModel(ctx)); 54 | } 55 | 56 | public async Task Search(string q, int page = 1) 57 | { 58 | var ctx = await getContext(); 59 | var query = string.IsNullOrWhiteSpace (q) ? string.Empty : q; 60 | var response = await ctx.Api.Form("everything") 61 | .Query(Predicates.fulltext("document", query)) 62 | .Ref (ctx.MaybeRef).PageSize (10).Page (page) 63 | .Submit (); 64 | 65 | ViewBag.Title = "Search results"; 66 | return View (new PrismicSearchResponse(ctx, response, q)); 67 | } 68 | 69 | public async Task Preview(string token) 70 | { 71 | var ctx = await getContext(); 72 | string url = await ctx.Api.PreviewSession (token, ctx.LinkResolver, "/"); 73 | var cookie = new HttpCookie (prismic.Api.PREVIEW_COOKIE, token); 74 | cookie.Expires = DateTime.Now.AddMinutes (30); 75 | this.ControllerContext.HttpContext.Response.SetCookie (cookie); 76 | return Redirect (url); 77 | } 78 | 79 | private async Task getContext() 80 | { 81 | var endpoint = WebConfigurationManager.AppSettings.Get("prismic.api.url"); 82 | var api = await new PrismicApiHome(endpoint).Get(); 83 | HttpCookie previewCookie = HttpContext.Request.Cookies.Get(prismic.Api.PREVIEW_COOKIE); 84 | string maybeRef = (previewCookie != null && previewCookie.Value != "") 85 | ? previewCookie.Value 86 | : api.Master.Reference; 87 | return new PrismicContext(endpoint, api, maybeRef, PrismicLinkResolver.Get(api, maybeRef, ControllerContext.RequestContext)); 88 | } 89 | } 90 | 91 | 92 | } 93 | 94 | 95 | -------------------------------------------------------------------------------- /src/prismic.starter/Scripts/respond.min.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */ 16 | /*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */ 17 | window.matchMedia=window.matchMedia||(function(e,f){var c,a=e.documentElement,b=a.firstElementChild||a.firstChild,d=e.createElement("body"),g=e.createElement("div");g.id="mq-test-1";g.style.cssText="position:absolute;top:-100em";d.style.background="none";d.appendChild(g);return function(h){g.innerHTML='­';a.insertBefore(d,b);c=g.offsetWidth==42;a.removeChild(d);return{matches:c,media:h}}})(document); 18 | 19 | /*! Respond.js v1.2.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */ 20 | (function(e){e.respond={};respond.update=function(){};respond.mediaQueriesSupported=e.matchMedia&&e.matchMedia("only all").matches;if(respond.mediaQueriesSupported){return}var w=e.document,s=w.documentElement,i=[],k=[],q=[],o={},h=30,f=w.getElementsByTagName("head")[0]||s,g=w.getElementsByTagName("base")[0],b=f.getElementsByTagName("link"),d=[],a=function(){var D=b,y=D.length,B=0,A,z,C,x;for(;B-1,minw:F.match(/\(min\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:F.match(/\(max\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}}j()},l,r,v=function(){var z,A=w.createElement("div"),x=w.body,y=false;A.style.cssText="position:absolute;font-size:1em;width:1em";if(!x){x=y=w.createElement("body");x.style.background="none"}x.appendChild(A);s.insertBefore(x,s.firstChild);z=A.offsetWidth;if(y){s.removeChild(x)}else{x.removeChild(A)}z=p=parseFloat(z);return z},p,j=function(I){var x="clientWidth",B=s[x],H=w.compatMode==="CSS1Compat"&&B||w.body[x]||B,D={},G=b[b.length-1],z=(new Date()).getTime();if(I&&l&&z-l-1?(p||v()):1)}if(!!J){J=parseFloat(J)*(J.indexOf(y)>-1?(p||v()):1)}if(!K.hasquery||(!A||!L)&&(A||H>=C)&&(L||H<=J)){if(!D[K.media]){D[K.media]=[]}D[K.media].push(k[K.rules])}}for(var E in q){if(q[E]&&q[E].parentNode===f){f.removeChild(q[E])}}for(var E in D){var M=w.createElement("style"),F=D[E].join("\n");M.type="text/css";M.media=E;f.insertBefore(M,G.nextSibling);if(M.styleSheet){M.styleSheet.cssText=F}else{M.appendChild(w.createTextNode(F))}q.push(M)}},n=function(x,z){var y=c();if(!y){return}y.open("GET",x,true);y.onreadystatechange=function(){if(y.readyState!=4||y.status!=200&&y.status!=304){return}z(y.responseText)};if(y.readyState==4){return}y.send(null)},c=(function(){var x=false;try{x=new XMLHttpRequest()}catch(y){x=new ActiveXObject("Microsoft.XMLHTTP")}return function(){return x}})();a();respond.update=a;function t(){j(true)}if(e.addEventListener){e.addEventListener("resize",t,false)}else{if(e.attachEvent){e.attachEvent("onresize",t)}}})(this); -------------------------------------------------------------------------------- /src/prismic.starter/Project_Readme.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Your ASP.NET application 6 | 95 | 96 | 97 | 98 | 102 | 103 |
104 |
105 |

This application consists of:

106 |
    107 |
  • Sample pages showing basic nav between Home, About, and Contact
  • 108 |
  • Theming using Bootstrap
  • 109 |
  • Authentication, if selected, shows how to register and sign in
  • 110 |
  • ASP.NET features managed using NuGet
  • 111 |
112 |
113 | 114 | 131 | 132 |
133 |

Deploy

134 | 139 |
140 | 141 |
142 |

Get help

143 | 147 |
148 |
149 | 150 | 151 | -------------------------------------------------------------------------------- /src/prismic.starter/Scripts/jquery.validate.unobtrusive.min.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /* 16 | ** Unobtrusive validation support library for jQuery and jQuery Validate 17 | ** Copyright (C) Microsoft Corporation. All rights reserved. 18 | */ 19 | (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(b){var c=a(b),f=c.data(e),i=a.proxy(n,b),g=d.unobtrusive.options||{},h=function(e,d){var c=g[e];c&&a.isFunction(c)&&c.apply(b,d)};if(!f){f={options:{errorClass:g.errorClass||"input-validation-error",errorElement:g.errorElement||"span",errorPlacement:function(){m.apply(b,arguments);h("errorPlacement",arguments)},invalidHandler:function(){l.apply(b,arguments);h("invalidHandler",arguments)},messages:{},rules:{},success:function(){k.apply(b,arguments);h("success",arguments)}},attachValidation:function(){c.off("reset."+e,i).on("reset."+e,i).validate(this.options)},validate:function(){c.validate();return c.valid()}};c.data(e,f)}return f}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(c){var b=a(c),e=b.parents().addBack().filter("form").add(b.find("form")).has("[data-val=true]");b.find("[data-val=true]").each(function(){d.unobtrusive.parseElement(this,true)});e.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});if(d.methods.extension){b.addSingleVal("accept","mimtype");b.addSingleVal("extension","extension")}else b.addSingleVal("extension","extension","accept");b.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.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength");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").filter("[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").filter("[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); -------------------------------------------------------------------------------- /src/prismic.starter/prismic.starter.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 8 | 9 | 2.0 10 | {E77D4793-5695-493C-913E-02115684B86A} 11 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} 12 | Library 13 | Properties 14 | prismic.starter 15 | prismic.starter 16 | v4.5 17 | false 18 | true 19 | 20 | 21 | 22 | 23 | 24 | 25 | true 26 | full 27 | false 28 | bin\ 29 | DEBUG;TRACE 30 | prompt 31 | 4 32 | 33 | 34 | pdbonly 35 | true 36 | bin\ 37 | TRACE 38 | prompt 39 | 4 40 | 41 | 42 | 43 | 44 | ..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll 45 | 46 | 47 | ..\packages\prismicio.1.1.0\lib\net45\prismicio.dll 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | True 69 | ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll 70 | 71 | 72 | 73 | 74 | 75 | 76 | True 77 | ..\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.Helpers.dll 78 | 79 | 80 | True 81 | ..\packages\Microsoft.AspNet.Mvc.5.2.2\lib\net45\System.Web.Mvc.dll 82 | 83 | 84 | ..\packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll 85 | 86 | 87 | True 88 | ..\packages\Microsoft.AspNet.Razor.3.2.2\lib\net45\System.Web.Razor.dll 89 | 90 | 91 | True 92 | ..\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.WebPages.dll 93 | 94 | 95 | True 96 | ..\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.WebPages.Deployment.dll 97 | 98 | 99 | True 100 | ..\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.WebPages.Razor.dll 101 | 102 | 103 | True 104 | ..\packages\WebGrease.1.5.2\lib\WebGrease.dll 105 | 106 | 107 | True 108 | ..\packages\Antlr.3.4.1.9004\lib\Antlr3.Runtime.dll 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | Global.asax 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | Web.config 151 | 152 | 153 | Web.config 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 10.0 177 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | True 190 | True 191 | 49913 192 | / 193 | http://localhost:49913/ 194 | False 195 | False 196 | 197 | 198 | False 199 | 200 | 201 | 202 | 203 | 209 | -------------------------------------------------------------------------------- /src/prismic.starter/Scripts/respond.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */ 16 | /*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */ 17 | window.matchMedia = window.matchMedia || (function(doc, undefined){ 18 | 19 | var bool, 20 | docElem = doc.documentElement, 21 | refNode = docElem.firstElementChild || docElem.firstChild, 22 | // fakeBody required for 23 | fakeBody = doc.createElement('body'), 24 | div = doc.createElement('div'); 25 | 26 | div.id = 'mq-test-1'; 27 | div.style.cssText = "position:absolute;top:-100em"; 28 | fakeBody.style.background = "none"; 29 | fakeBody.appendChild(div); 30 | 31 | return function(q){ 32 | 33 | div.innerHTML = '­'; 34 | 35 | docElem.insertBefore(fakeBody, refNode); 36 | bool = div.offsetWidth == 42; 37 | docElem.removeChild(fakeBody); 38 | 39 | return { matches: bool, media: q }; 40 | }; 41 | 42 | })(document); 43 | 44 | 45 | 46 | 47 | /*! Respond.js v1.2.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */ 48 | (function( win ){ 49 | //exposed namespace 50 | win.respond = {}; 51 | 52 | //define update even in native-mq-supporting browsers, to avoid errors 53 | respond.update = function(){}; 54 | 55 | //expose media query support flag for external use 56 | respond.mediaQueriesSupported = win.matchMedia && win.matchMedia( "only all" ).matches; 57 | 58 | //if media queries are supported, exit here 59 | if( respond.mediaQueriesSupported ){ return; } 60 | 61 | //define vars 62 | var doc = win.document, 63 | docElem = doc.documentElement, 64 | mediastyles = [], 65 | rules = [], 66 | appendedEls = [], 67 | parsedSheets = {}, 68 | resizeThrottle = 30, 69 | head = doc.getElementsByTagName( "head" )[0] || docElem, 70 | base = doc.getElementsByTagName( "base" )[0], 71 | links = head.getElementsByTagName( "link" ), 72 | requestQueue = [], 73 | 74 | //loop stylesheets, send text content to translate 75 | ripCSS = function(){ 76 | var sheets = links, 77 | sl = sheets.length, 78 | i = 0, 79 | //vars for loop: 80 | sheet, href, media, isCSS; 81 | 82 | for( ; i < sl; i++ ){ 83 | sheet = sheets[ i ], 84 | href = sheet.href, 85 | media = sheet.media, 86 | isCSS = sheet.rel && sheet.rel.toLowerCase() === "stylesheet"; 87 | 88 | //only links plz and prevent re-parsing 89 | if( !!href && isCSS && !parsedSheets[ href ] ){ 90 | // selectivizr exposes css through the rawCssText expando 91 | if (sheet.styleSheet && sheet.styleSheet.rawCssText) { 92 | translate( sheet.styleSheet.rawCssText, href, media ); 93 | parsedSheets[ href ] = true; 94 | } else { 95 | if( (!/^([a-zA-Z:]*\/\/)/.test( href ) && !base) 96 | || href.replace( RegExp.$1, "" ).split( "/" )[0] === win.location.host ){ 97 | requestQueue.push( { 98 | href: href, 99 | media: media 100 | } ); 101 | } 102 | } 103 | } 104 | } 105 | makeRequests(); 106 | }, 107 | 108 | //recurse through request queue, get css text 109 | makeRequests = function(){ 110 | if( requestQueue.length ){ 111 | var thisRequest = requestQueue.shift(); 112 | 113 | ajax( thisRequest.href, function( styles ){ 114 | translate( styles, thisRequest.href, thisRequest.media ); 115 | parsedSheets[ thisRequest.href ] = true; 116 | makeRequests(); 117 | } ); 118 | } 119 | }, 120 | 121 | //find media blocks in css text, convert to style blocks 122 | translate = function( styles, href, media ){ 123 | var qs = styles.match( /@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi ), 124 | ql = qs && qs.length || 0, 125 | //try to get CSS path 126 | href = href.substring( 0, href.lastIndexOf( "/" )), 127 | repUrls = function( css ){ 128 | return css.replace( /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g, "$1" + href + "$2$3" ); 129 | }, 130 | useMedia = !ql && media, 131 | //vars used in loop 132 | i = 0, 133 | j, fullq, thisq, eachq, eql; 134 | 135 | //if path exists, tack on trailing slash 136 | if( href.length ){ href += "/"; } 137 | 138 | //if no internal queries exist, but media attr does, use that 139 | //note: this currently lacks support for situations where a media attr is specified on a link AND 140 | //its associated stylesheet has internal CSS media queries. 141 | //In those cases, the media attribute will currently be ignored. 142 | if( useMedia ){ 143 | ql = 1; 144 | } 145 | 146 | 147 | for( ; i < ql; i++ ){ 148 | j = 0; 149 | 150 | //media attr 151 | if( useMedia ){ 152 | fullq = media; 153 | rules.push( repUrls( styles ) ); 154 | } 155 | //parse for styles 156 | else{ 157 | fullq = qs[ i ].match( /@media *([^\{]+)\{([\S\s]+?)$/ ) && RegExp.$1; 158 | rules.push( RegExp.$2 && repUrls( RegExp.$2 ) ); 159 | } 160 | 161 | eachq = fullq.split( "," ); 162 | eql = eachq.length; 163 | 164 | for( ; j < eql; j++ ){ 165 | thisq = eachq[ j ]; 166 | mediastyles.push( { 167 | media : thisq.split( "(" )[ 0 ].match( /(only\s+)?([a-zA-Z]+)\s?/ ) && RegExp.$2 || "all", 168 | rules : rules.length - 1, 169 | hasquery: thisq.indexOf("(") > -1, 170 | minw : thisq.match( /\(min\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" ), 171 | maxw : thisq.match( /\(max\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" ) 172 | } ); 173 | } 174 | } 175 | 176 | applyMedia(); 177 | }, 178 | 179 | lastCall, 180 | 181 | resizeDefer, 182 | 183 | // returns the value of 1em in pixels 184 | getEmValue = function() { 185 | var ret, 186 | div = doc.createElement('div'), 187 | body = doc.body, 188 | fakeUsed = false; 189 | 190 | div.style.cssText = "position:absolute;font-size:1em;width:1em"; 191 | 192 | if( !body ){ 193 | body = fakeUsed = doc.createElement( "body" ); 194 | body.style.background = "none"; 195 | } 196 | 197 | body.appendChild( div ); 198 | 199 | docElem.insertBefore( body, docElem.firstChild ); 200 | 201 | ret = div.offsetWidth; 202 | 203 | if( fakeUsed ){ 204 | docElem.removeChild( body ); 205 | } 206 | else { 207 | body.removeChild( div ); 208 | } 209 | 210 | //also update eminpx before returning 211 | ret = eminpx = parseFloat(ret); 212 | 213 | return ret; 214 | }, 215 | 216 | //cached container for 1em value, populated the first time it's needed 217 | eminpx, 218 | 219 | //enable/disable styles 220 | applyMedia = function( fromResize ){ 221 | var name = "clientWidth", 222 | docElemProp = docElem[ name ], 223 | currWidth = doc.compatMode === "CSS1Compat" && docElemProp || doc.body[ name ] || docElemProp, 224 | styleBlocks = {}, 225 | lastLink = links[ links.length-1 ], 226 | now = (new Date()).getTime(); 227 | 228 | //throttle resize calls 229 | if( fromResize && lastCall && now - lastCall < resizeThrottle ){ 230 | clearTimeout( resizeDefer ); 231 | resizeDefer = setTimeout( applyMedia, resizeThrottle ); 232 | return; 233 | } 234 | else { 235 | lastCall = now; 236 | } 237 | 238 | for( var i in mediastyles ){ 239 | var thisstyle = mediastyles[ i ], 240 | min = thisstyle.minw, 241 | max = thisstyle.maxw, 242 | minnull = min === null, 243 | maxnull = max === null, 244 | em = "em"; 245 | 246 | if( !!min ){ 247 | min = parseFloat( min ) * ( min.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 ); 248 | } 249 | if( !!max ){ 250 | max = parseFloat( max ) * ( max.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 ); 251 | } 252 | 253 | // if there's no media query at all (the () part), or min or max is not null, and if either is present, they're true 254 | if( !thisstyle.hasquery || ( !minnull || !maxnull ) && ( minnull || currWidth >= min ) && ( maxnull || currWidth <= max ) ){ 255 | if( !styleBlocks[ thisstyle.media ] ){ 256 | styleBlocks[ thisstyle.media ] = []; 257 | } 258 | styleBlocks[ thisstyle.media ].push( rules[ thisstyle.rules ] ); 259 | } 260 | } 261 | 262 | //remove any existing respond style element(s) 263 | for( var i in appendedEls ){ 264 | if( appendedEls[ i ] && appendedEls[ i ].parentNode === head ){ 265 | head.removeChild( appendedEls[ i ] ); 266 | } 267 | } 268 | 269 | //inject active styles, grouped by media type 270 | for( var i in styleBlocks ){ 271 | var ss = doc.createElement( "style" ), 272 | css = styleBlocks[ i ].join( "\n" ); 273 | 274 | ss.type = "text/css"; 275 | ss.media = i; 276 | 277 | //originally, ss was appended to a documentFragment and sheets were appended in bulk. 278 | //this caused crashes in IE in a number of circumstances, such as when the HTML element had a bg image set, so appending beforehand seems best. Thanks to @dvelyk for the initial research on this one! 279 | head.insertBefore( ss, lastLink.nextSibling ); 280 | 281 | if ( ss.styleSheet ){ 282 | ss.styleSheet.cssText = css; 283 | } 284 | else { 285 | ss.appendChild( doc.createTextNode( css ) ); 286 | } 287 | 288 | //push to appendedEls to track for later removal 289 | appendedEls.push( ss ); 290 | } 291 | }, 292 | //tweaked Ajax functions from Quirksmode 293 | ajax = function( url, callback ) { 294 | var req = xmlHttp(); 295 | if (!req){ 296 | return; 297 | } 298 | req.open( "GET", url, true ); 299 | req.onreadystatechange = function () { 300 | if ( req.readyState != 4 || req.status != 200 && req.status != 304 ){ 301 | return; 302 | } 303 | callback( req.responseText ); 304 | } 305 | if ( req.readyState == 4 ){ 306 | return; 307 | } 308 | req.send( null ); 309 | }, 310 | //define ajax obj 311 | xmlHttp = (function() { 312 | var xmlhttpmethod = false; 313 | try { 314 | xmlhttpmethod = new XMLHttpRequest(); 315 | } 316 | catch( e ){ 317 | xmlhttpmethod = new ActiveXObject( "Microsoft.XMLHTTP" ); 318 | } 319 | return function(){ 320 | return xmlhttpmethod; 321 | }; 322 | })(); 323 | 324 | //translate CSS 325 | ripCSS(); 326 | 327 | //expose update for re-running respond later on 328 | respond.update = ripCSS; 329 | 330 | //adjust on resize 331 | function callMedia(){ 332 | applyMedia( true ); 333 | } 334 | if( win.addEventListener ){ 335 | win.addEventListener( "resize", callMedia, false ); 336 | } 337 | else if( win.attachEvent ){ 338 | win.attachEvent( "onresize", callMedia ); 339 | } 340 | })(this); 341 | -------------------------------------------------------------------------------- /src/prismic.starter/Scripts/jquery.validate.unobtrusive.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /*! 16 | ** Unobtrusive validation support library for jQuery and jQuery Validate 17 | ** Copyright (C) Microsoft Corporation. All rights reserved. 18 | */ 19 | 20 | /*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */ 21 | /*global document: false, jQuery: false */ 22 | 23 | (function ($) { 24 | var $jQval = $.validator, 25 | adapters, 26 | data_validation = "unobtrusiveValidation"; 27 | 28 | function setValidationValues(options, ruleName, value) { 29 | options.rules[ruleName] = value; 30 | if (options.message) { 31 | options.messages[ruleName] = options.message; 32 | } 33 | } 34 | 35 | function splitAndTrim(value) { 36 | return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g); 37 | } 38 | 39 | function escapeAttributeValue(value) { 40 | // As mentioned on http://api.jquery.com/category/selectors/ 41 | return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1"); 42 | } 43 | 44 | function getModelPrefix(fieldName) { 45 | return fieldName.substr(0, fieldName.lastIndexOf(".") + 1); 46 | } 47 | 48 | function appendModelPrefix(value, prefix) { 49 | if (value.indexOf("*.") === 0) { 50 | value = value.replace("*.", prefix); 51 | } 52 | return value; 53 | } 54 | 55 | function onError(error, inputElement) { // 'this' is the form element 56 | var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"), 57 | replaceAttrValue = container.attr("data-valmsg-replace"), 58 | replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null; 59 | 60 | container.removeClass("field-validation-valid").addClass("field-validation-error"); 61 | error.data("unobtrusiveContainer", container); 62 | 63 | if (replace) { 64 | container.empty(); 65 | error.removeClass("input-validation-error").appendTo(container); 66 | } 67 | else { 68 | error.hide(); 69 | } 70 | } 71 | 72 | function onErrors(event, validator) { // 'this' is the form element 73 | var container = $(this).find("[data-valmsg-summary=true]"), 74 | list = container.find("ul"); 75 | 76 | if (list && list.length && validator.errorList.length) { 77 | list.empty(); 78 | container.addClass("validation-summary-errors").removeClass("validation-summary-valid"); 79 | 80 | $.each(validator.errorList, function () { 81 | $("
  • ").html(this.message).appendTo(list); 82 | }); 83 | } 84 | } 85 | 86 | function onSuccess(error) { // 'this' is the form element 87 | var container = error.data("unobtrusiveContainer"), 88 | replaceAttrValue = container.attr("data-valmsg-replace"), 89 | replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null; 90 | 91 | if (container) { 92 | container.addClass("field-validation-valid").removeClass("field-validation-error"); 93 | error.removeData("unobtrusiveContainer"); 94 | 95 | if (replace) { 96 | container.empty(); 97 | } 98 | } 99 | } 100 | 101 | function onReset(event) { // 'this' is the form element 102 | var $form = $(this); 103 | $form.data("validator").resetForm(); 104 | $form.find(".validation-summary-errors") 105 | .addClass("validation-summary-valid") 106 | .removeClass("validation-summary-errors"); 107 | $form.find(".field-validation-error") 108 | .addClass("field-validation-valid") 109 | .removeClass("field-validation-error") 110 | .removeData("unobtrusiveContainer") 111 | .find(">*") // If we were using valmsg-replace, get the underlying error 112 | .removeData("unobtrusiveContainer"); 113 | } 114 | 115 | function validationInfo(form) { 116 | var $form = $(form), 117 | result = $form.data(data_validation), 118 | onResetProxy = $.proxy(onReset, form), 119 | defaultOptions = $jQval.unobtrusive.options || {}, 120 | execInContext = function (name, args) { 121 | var func = defaultOptions[name]; 122 | func && $.isFunction(func) && func.apply(form, args); 123 | } 124 | 125 | if (!result) { 126 | result = { 127 | options: { // options structure passed to jQuery Validate's validate() method 128 | errorClass: defaultOptions.errorClass || "input-validation-error", 129 | errorElement: defaultOptions.errorElement || "span", 130 | errorPlacement: function () { 131 | onError.apply(form, arguments); 132 | execInContext("errorPlacement", arguments); 133 | }, 134 | invalidHandler: function () { 135 | onErrors.apply(form, arguments); 136 | execInContext("invalidHandler", arguments); 137 | }, 138 | messages: {}, 139 | rules: {}, 140 | success: function () { 141 | onSuccess.apply(form, arguments); 142 | execInContext("success", arguments); 143 | } 144 | }, 145 | attachValidation: function () { 146 | $form 147 | .off("reset." + data_validation, onResetProxy) 148 | .on("reset." + data_validation, onResetProxy) 149 | .validate(this.options); 150 | }, 151 | validate: function () { // a validation function that is called by unobtrusive Ajax 152 | $form.validate(); 153 | return $form.valid(); 154 | } 155 | }; 156 | $form.data(data_validation, result); 157 | } 158 | 159 | return result; 160 | } 161 | 162 | $jQval.unobtrusive = { 163 | adapters: [], 164 | 165 | parseElement: function (element, skipAttach) { 166 | /// 167 | /// Parses a single HTML element for unobtrusive validation attributes. 168 | /// 169 | /// The HTML element to be parsed. 170 | /// [Optional] true to skip attaching the 171 | /// validation to the form. If parsing just this single element, you should specify true. 172 | /// If parsing several elements, you should specify false, and manually attach the validation 173 | /// to the form when you are finished. The default is false. 174 | var $element = $(element), 175 | form = $element.parents("form")[0], 176 | valInfo, rules, messages; 177 | 178 | if (!form) { // Cannot do client-side validation without a form 179 | return; 180 | } 181 | 182 | valInfo = validationInfo(form); 183 | valInfo.options.rules[element.name] = rules = {}; 184 | valInfo.options.messages[element.name] = messages = {}; 185 | 186 | $.each(this.adapters, function () { 187 | var prefix = "data-val-" + this.name, 188 | message = $element.attr(prefix), 189 | paramValues = {}; 190 | 191 | if (message !== undefined) { // Compare against undefined, because an empty message is legal (and falsy) 192 | prefix += "-"; 193 | 194 | $.each(this.params, function () { 195 | paramValues[this] = $element.attr(prefix + this); 196 | }); 197 | 198 | this.adapt({ 199 | element: element, 200 | form: form, 201 | message: message, 202 | params: paramValues, 203 | rules: rules, 204 | messages: messages 205 | }); 206 | } 207 | }); 208 | 209 | $.extend(rules, { "__dummy__": true }); 210 | 211 | if (!skipAttach) { 212 | valInfo.attachValidation(); 213 | } 214 | }, 215 | 216 | parse: function (selector) { 217 | /// 218 | /// Parses all the HTML elements in the specified selector. It looks for input elements decorated 219 | /// with the [data-val=true] attribute value and enables validation according to the data-val-* 220 | /// attribute values. 221 | /// 222 | /// Any valid jQuery selector. 223 | 224 | // $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one 225 | // element with data-val=true 226 | var $selector = $(selector), 227 | $forms = $selector.parents() 228 | .addBack() 229 | .filter("form") 230 | .add($selector.find("form")) 231 | .has("[data-val=true]"); 232 | 233 | $selector.find("[data-val=true]").each(function () { 234 | $jQval.unobtrusive.parseElement(this, true); 235 | }); 236 | 237 | $forms.each(function () { 238 | var info = validationInfo(this); 239 | if (info) { 240 | info.attachValidation(); 241 | } 242 | }); 243 | } 244 | }; 245 | 246 | adapters = $jQval.unobtrusive.adapters; 247 | 248 | adapters.add = function (adapterName, params, fn) { 249 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation. 250 | /// The name of the adapter to be added. This matches the name used 251 | /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name). 252 | /// [Optional] An array of parameter names (strings) that will 253 | /// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and 254 | /// mmmm is the parameter name). 255 | /// The function to call, which adapts the values from the HTML 256 | /// attributes into jQuery Validate rules and/or messages. 257 | /// 258 | if (!fn) { // Called with no params, just a function 259 | fn = params; 260 | params = []; 261 | } 262 | this.push({ name: adapterName, params: params, adapt: fn }); 263 | return this; 264 | }; 265 | 266 | adapters.addBool = function (adapterName, ruleName) { 267 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where 268 | /// the jQuery Validate validation rule has no parameter values. 269 | /// The name of the adapter to be added. This matches the name used 270 | /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name). 271 | /// [Optional] The name of the jQuery Validate rule. If not provided, the value 272 | /// of adapterName will be used instead. 273 | /// 274 | return this.add(adapterName, function (options) { 275 | setValidationValues(options, ruleName || adapterName, true); 276 | }); 277 | }; 278 | 279 | adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) { 280 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where 281 | /// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and 282 | /// one for min-and-max). The HTML parameters are expected to be named -min and -max. 283 | /// The name of the adapter to be added. This matches the name used 284 | /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name). 285 | /// The name of the jQuery Validate rule to be used when you only 286 | /// have a minimum value. 287 | /// The name of the jQuery Validate rule to be used when you only 288 | /// have a maximum value. 289 | /// The name of the jQuery Validate rule to be used when you 290 | /// have both a minimum and maximum value. 291 | /// [Optional] The name of the HTML attribute that 292 | /// contains the minimum value. The default is "min". 293 | /// [Optional] The name of the HTML attribute that 294 | /// contains the maximum value. The default is "max". 295 | /// 296 | return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) { 297 | var min = options.params.min, 298 | max = options.params.max; 299 | 300 | if (min && max) { 301 | setValidationValues(options, minMaxRuleName, [min, max]); 302 | } 303 | else if (min) { 304 | setValidationValues(options, minRuleName, min); 305 | } 306 | else if (max) { 307 | setValidationValues(options, maxRuleName, max); 308 | } 309 | }); 310 | }; 311 | 312 | adapters.addSingleVal = function (adapterName, attribute, ruleName) { 313 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where 314 | /// the jQuery Validate validation rule has a single value. 315 | /// The name of the adapter to be added. This matches the name used 316 | /// in the data-val-nnnn HTML attribute(where nnnn is the adapter name). 317 | /// [Optional] The name of the HTML attribute that contains the value. 318 | /// The default is "val". 319 | /// [Optional] The name of the jQuery Validate rule. If not provided, the value 320 | /// of adapterName will be used instead. 321 | /// 322 | return this.add(adapterName, [attribute || "val"], function (options) { 323 | setValidationValues(options, ruleName || adapterName, options.params[attribute]); 324 | }); 325 | }; 326 | 327 | $jQval.addMethod("__dummy__", function (value, element, params) { 328 | return true; 329 | }); 330 | 331 | $jQval.addMethod("regex", function (value, element, params) { 332 | var match; 333 | if (this.optional(element)) { 334 | return true; 335 | } 336 | 337 | match = new RegExp(params).exec(value); 338 | return (match && (match.index === 0) && (match[0].length === value.length)); 339 | }); 340 | 341 | $jQval.addMethod("nonalphamin", function (value, element, nonalphamin) { 342 | var match; 343 | if (nonalphamin) { 344 | match = value.match(/\W/g); 345 | match = match && match.length >= nonalphamin; 346 | } 347 | return match; 348 | }); 349 | 350 | if ($jQval.methods.extension) { 351 | adapters.addSingleVal("accept", "mimtype"); 352 | adapters.addSingleVal("extension", "extension"); 353 | } else { 354 | // for backward compatibility, when the 'extension' validation method does not exist, such as with versions 355 | // of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for 356 | // validating the extension, and ignore mime-type validations as they are not supported. 357 | adapters.addSingleVal("extension", "extension", "accept"); 358 | } 359 | 360 | adapters.addSingleVal("regex", "pattern"); 361 | adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"); 362 | adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range"); 363 | adapters.addMinMax("minlength", "minlength").addMinMax("maxlength", "minlength", "maxlength"); 364 | adapters.add("equalto", ["other"], function (options) { 365 | var prefix = getModelPrefix(options.element.name), 366 | other = options.params.other, 367 | fullOtherName = appendModelPrefix(other, prefix), 368 | element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0]; 369 | 370 | setValidationValues(options, "equalTo", element); 371 | }); 372 | adapters.add("required", function (options) { 373 | // jQuery Validate equates "required" with "mandatory" for checkbox elements 374 | if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") { 375 | setValidationValues(options, "required", true); 376 | } 377 | }); 378 | adapters.add("remote", ["url", "type", "additionalfields"], function (options) { 379 | var value = { 380 | url: options.params.url, 381 | type: options.params.type || "GET", 382 | data: {} 383 | }, 384 | prefix = getModelPrefix(options.element.name); 385 | 386 | $.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) { 387 | var paramName = appendModelPrefix(fieldName, prefix); 388 | value.data[paramName] = function () { 389 | return $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']").val(); 390 | }; 391 | }); 392 | 393 | setValidationValues(options, "remote", value); 394 | }); 395 | adapters.add("password", ["min", "nonalphamin", "regex"], function (options) { 396 | if (options.params.min) { 397 | setValidationValues(options, "minlength", options.params.min); 398 | } 399 | if (options.params.nonalphamin) { 400 | setValidationValues(options, "nonalphamin", options.params.nonalphamin); 401 | } 402 | if (options.params.regex) { 403 | setValidationValues(options, "regex", options.params.regex); 404 | } 405 | }); 406 | 407 | $(function () { 408 | $jQval.unobtrusive.parse(document); 409 | }); 410 | }(jQuery)); -------------------------------------------------------------------------------- /src/prismic.starter/Scripts/jquery.validate.min.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /*! jQuery Validation Plugin - v1.11.1 - 3/22/2013\n* https://github.com/jzaefferer/jquery-validation 16 | * Copyright (c) 2013 Jörn Zaefferer; Licensed MIT */(function(t){t.extend(t.fn,{validate:function(e){if(!this.length)return e&&e.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing."),void 0;var i=t.data(this[0],"validator");return i?i:(this.attr("novalidate","novalidate"),i=new t.validator(e,this[0]),t.data(this[0],"validator",i),i.settings.onsubmit&&(this.validateDelegate(":submit","click",function(e){i.settings.submitHandler&&(i.submitButton=e.target),t(e.target).hasClass("cancel")&&(i.cancelSubmit=!0),void 0!==t(e.target).attr("formnovalidate")&&(i.cancelSubmit=!0)}),this.submit(function(e){function s(){var s;return i.settings.submitHandler?(i.submitButton&&(s=t("").attr("name",i.submitButton.name).val(t(i.submitButton).val()).appendTo(i.currentForm)),i.settings.submitHandler.call(i,i.currentForm,e),i.submitButton&&s.remove(),!1):!0}return i.settings.debug&&e.preventDefault(),i.cancelSubmit?(i.cancelSubmit=!1,s()):i.form()?i.pendingRequest?(i.formSubmitted=!0,!1):s():(i.focusInvalid(),!1)})),i)},valid:function(){if(t(this[0]).is("form"))return this.validate().form();var e=!0,i=t(this[0].form).validate();return this.each(function(){e=e&&i.element(this)}),e},removeAttrs:function(e){var i={},s=this;return t.each(e.split(/\s/),function(t,e){i[e]=s.attr(e),s.removeAttr(e)}),i},rules:function(e,i){var s=this[0];if(e){var r=t.data(s.form,"validator").settings,n=r.rules,a=t.validator.staticRules(s);switch(e){case"add":t.extend(a,t.validator.normalizeRule(i)),delete a.messages,n[s.name]=a,i.messages&&(r.messages[s.name]=t.extend(r.messages[s.name],i.messages));break;case"remove":if(!i)return delete n[s.name],a;var u={};return t.each(i.split(/\s/),function(t,e){u[e]=a[e],delete a[e]}),u}}var o=t.validator.normalizeRules(t.extend({},t.validator.classRules(s),t.validator.attributeRules(s),t.validator.dataRules(s),t.validator.staticRules(s)),s);if(o.required){var l=o.required;delete o.required,o=t.extend({required:l},o)}return o}}),t.extend(t.expr[":"],{blank:function(e){return!t.trim(""+t(e).val())},filled:function(e){return!!t.trim(""+t(e).val())},unchecked:function(e){return!t(e).prop("checked")}}),t.validator=function(e,i){this.settings=t.extend(!0,{},t.validator.defaults,e),this.currentForm=i,this.init()},t.validator.format=function(e,i){return 1===arguments.length?function(){var i=t.makeArray(arguments);return i.unshift(e),t.validator.format.apply(this,i)}:(arguments.length>2&&i.constructor!==Array&&(i=t.makeArray(arguments).slice(1)),i.constructor!==Array&&(i=[i]),t.each(i,function(t,i){e=e.replace(RegExp("\\{"+t+"\\}","g"),function(){return i})}),e)},t.extend(t.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",validClass:"valid",errorElement:"label",focusInvalid:!0,errorContainer:t([]),errorLabelContainer:t([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(t){this.lastActive=t,this.settings.focusCleanup&&!this.blockFocusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,t,this.settings.errorClass,this.settings.validClass),this.addWrapper(this.errorsFor(t)).hide())},onfocusout:function(t){this.checkable(t)||!(t.name in this.submitted)&&this.optional(t)||this.element(t)},onkeyup:function(t,e){(9!==e.which||""!==this.elementValue(t))&&(t.name in this.submitted||t===this.lastElement)&&this.element(t)},onclick:function(t){t.name in this.submitted?this.element(t):t.parentNode.name in this.submitted&&this.element(t.parentNode)},highlight:function(e,i,s){"radio"===e.type?this.findByName(e.name).addClass(i).removeClass(s):t(e).addClass(i).removeClass(s)},unhighlight:function(e,i,s){"radio"===e.type?this.findByName(e.name).removeClass(i).addClass(s):t(e).removeClass(i).addClass(s)}},setDefaults:function(e){t.extend(t.validator.defaults,e)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",maxlength:t.validator.format("Please enter no more than {0} characters."),minlength:t.validator.format("Please enter at least {0} characters."),rangelength:t.validator.format("Please enter a value between {0} and {1} characters long."),range:t.validator.format("Please enter a value between {0} and {1}."),max:t.validator.format("Please enter a value less than or equal to {0}."),min:t.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:!1,prototype:{init:function(){function e(e){var i=t.data(this[0].form,"validator"),s="on"+e.type.replace(/^validate/,"");i.settings[s]&&i.settings[s].call(i,this[0],e)}this.labelContainer=t(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||t(this.currentForm),this.containers=t(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var i=this.groups={};t.each(this.settings.groups,function(e,s){"string"==typeof s&&(s=s.split(/\s/)),t.each(s,function(t,s){i[s]=e})});var s=this.settings.rules;t.each(s,function(e,i){s[e]=t.validator.normalizeRule(i)}),t(this.currentForm).validateDelegate(":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'] ,[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'] ","focusin focusout keyup",e).validateDelegate("[type='radio'], [type='checkbox'], select, option","click",e),this.settings.invalidHandler&&t(this.currentForm).bind("invalid-form.validate",this.settings.invalidHandler)},form:function(){return this.checkForm(),t.extend(this.submitted,this.errorMap),this.invalid=t.extend({},this.errorMap),this.valid()||t(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var t=0,e=this.currentElements=this.elements();e[t];t++)this.check(e[t]);return this.valid()},element:function(e){e=this.validationTargetFor(this.clean(e)),this.lastElement=e,this.prepareElement(e),this.currentElements=t(e);var i=this.check(e)!==!1;return i?delete this.invalid[e.name]:this.invalid[e.name]=!0,this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),i},showErrors:function(e){if(e){t.extend(this.errorMap,e),this.errorList=[];for(var i in e)this.errorList.push({message:e[i],element:this.findByName(i)[0]});this.successList=t.grep(this.successList,function(t){return!(t.name in e)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){t.fn.resetForm&&t(this.currentForm).resetForm(),this.submitted={},this.lastElement=null,this.prepareForm(),this.hideErrors(),this.elements().removeClass(this.settings.errorClass).removeData("previousValue")},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(t){var e=0;for(var i in t)e++;return e},hideErrors:function(){this.addWrapper(this.toHide).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{t(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(e){}},findLastActive:function(){var e=this.lastActive;return e&&1===t.grep(this.errorList,function(t){return t.element.name===e.name}).length&&e},elements:function(){var e=this,i={};return t(this.currentForm).find("input, select, textarea").not(":submit, :reset, :image, [disabled]").not(this.settings.ignore).filter(function(){return!this.name&&e.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.name in i||!e.objectLength(t(this).rules())?!1:(i[this.name]=!0,!0)})},clean:function(e){return t(e)[0]},errors:function(){var e=this.settings.errorClass.replace(" ",".");return t(this.settings.errorElement+"."+e,this.errorContext)},reset:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=t([]),this.toHide=t([]),this.currentElements=t([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(t){this.reset(),this.toHide=this.errorsFor(t)},elementValue:function(e){var i=t(e).attr("type"),s=t(e).val();return"radio"===i||"checkbox"===i?t("input[name='"+t(e).attr("name")+"']:checked").val():"string"==typeof s?s.replace(/\r/g,""):s},check:function(e){e=this.validationTargetFor(this.clean(e));var i,s=t(e).rules(),r=!1,n=this.elementValue(e);for(var a in s){var u={method:a,parameters:s[a]};try{if(i=t.validator.methods[a].call(this,n,e,u.parameters),"dependency-mismatch"===i){r=!0;continue}if(r=!1,"pending"===i)return this.toHide=this.toHide.not(this.errorsFor(e)),void 0;if(!i)return this.formatAndAdd(e,u),!1}catch(o){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+e.id+", check the '"+u.method+"' method.",o),o}}return r?void 0:(this.objectLength(s)&&this.successList.push(e),!0)},customDataMessage:function(e,i){return t(e).data("msg-"+i.toLowerCase())||e.attributes&&t(e).attr("data-msg-"+i.toLowerCase())},customMessage:function(t,e){var i=this.settings.messages[t];return i&&(i.constructor===String?i:i[e])},findDefined:function(){for(var t=0;arguments.length>t;t++)if(void 0!==arguments[t])return arguments[t];return void 0},defaultMessage:function(e,i){return this.findDefined(this.customMessage(e.name,i),this.customDataMessage(e,i),!this.settings.ignoreTitle&&e.title||void 0,t.validator.messages[i],"Warning: No message defined for "+e.name+"")},formatAndAdd:function(e,i){var s=this.defaultMessage(e,i.method),r=/\$?\{(\d+)\}/g;"function"==typeof s?s=s.call(this,i.parameters,e):r.test(s)&&(s=t.validator.format(s.replace(r,"{$1}"),i.parameters)),this.errorList.push({message:s,element:e}),this.errorMap[e.name]=s,this.submitted[e.name]=s},addWrapper:function(t){return this.settings.wrapper&&(t=t.add(t.parent(this.settings.wrapper))),t},defaultShowErrors:function(){var t,e;for(t=0;this.errorList[t];t++){var i=this.errorList[t];this.settings.highlight&&this.settings.highlight.call(this,i.element,this.settings.errorClass,this.settings.validClass),this.showLabel(i.element,i.message)}if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(t=0;this.successList[t];t++)this.showLabel(this.successList[t]);if(this.settings.unhighlight)for(t=0,e=this.validElements();e[t];t++)this.settings.unhighlight.call(this,e[t],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return t(this.errorList).map(function(){return this.element})},showLabel:function(e,i){var s=this.errorsFor(e);s.length?(s.removeClass(this.settings.validClass).addClass(this.settings.errorClass),s.html(i)):(s=t("<"+this.settings.errorElement+">").attr("for",this.idOrName(e)).addClass(this.settings.errorClass).html(i||""),this.settings.wrapper&&(s=s.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.append(s).length||(this.settings.errorPlacement?this.settings.errorPlacement(s,t(e)):s.insertAfter(e))),!i&&this.settings.success&&(s.text(""),"string"==typeof this.settings.success?s.addClass(this.settings.success):this.settings.success(s,e)),this.toShow=this.toShow.add(s)},errorsFor:function(e){var i=this.idOrName(e);return this.errors().filter(function(){return t(this).attr("for")===i})},idOrName:function(t){return this.groups[t.name]||(this.checkable(t)?t.name:t.id||t.name)},validationTargetFor:function(t){return this.checkable(t)&&(t=this.findByName(t.name).not(this.settings.ignore)[0]),t},checkable:function(t){return/radio|checkbox/i.test(t.type)},findByName:function(e){return t(this.currentForm).find("[name='"+e+"']")},getLength:function(e,i){switch(i.nodeName.toLowerCase()){case"select":return t("option:selected",i).length;case"input":if(this.checkable(i))return this.findByName(i.name).filter(":checked").length}return e.length},depend:function(t,e){return this.dependTypes[typeof t]?this.dependTypes[typeof t](t,e):!0},dependTypes:{"boolean":function(t){return t},string:function(e,i){return!!t(e,i.form).length},"function":function(t,e){return t(e)}},optional:function(e){var i=this.elementValue(e);return!t.validator.methods.required.call(this,i,e)&&"dependency-mismatch"},startRequest:function(t){this.pending[t.name]||(this.pendingRequest++,this.pending[t.name]=!0)},stopRequest:function(e,i){this.pendingRequest--,0>this.pendingRequest&&(this.pendingRequest=0),delete this.pending[e.name],i&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(t(this.currentForm).submit(),this.formSubmitted=!1):!i&&0===this.pendingRequest&&this.formSubmitted&&(t(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(e){return t.data(e,"previousValue")||t.data(e,"previousValue",{old:null,valid:!0,message:this.defaultMessage(e,"remote")})}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(e,i){e.constructor===String?this.classRuleSettings[e]=i:t.extend(this.classRuleSettings,e)},classRules:function(e){var i={},s=t(e).attr("class");return s&&t.each(s.split(" "),function(){this in t.validator.classRuleSettings&&t.extend(i,t.validator.classRuleSettings[this])}),i},attributeRules:function(e){var i={},s=t(e),r=s[0].getAttribute("type");for(var n in t.validator.methods){var a;"required"===n?(a=s.get(0).getAttribute(n),""===a&&(a=!0),a=!!a):a=s.attr(n),/min|max/.test(n)&&(null===r||/number|range|text/.test(r))&&(a=Number(a)),a?i[n]=a:r===n&&"range"!==r&&(i[n]=!0)}return i.maxlength&&/-1|2147483647|524288/.test(i.maxlength)&&delete i.maxlength,i},dataRules:function(e){var i,s,r={},n=t(e);for(i in t.validator.methods)s=n.data("rule-"+i.toLowerCase()),void 0!==s&&(r[i]=s);return r},staticRules:function(e){var i={},s=t.data(e.form,"validator");return s.settings.rules&&(i=t.validator.normalizeRule(s.settings.rules[e.name])||{}),i},normalizeRules:function(e,i){return t.each(e,function(s,r){if(r===!1)return delete e[s],void 0;if(r.param||r.depends){var n=!0;switch(typeof r.depends){case"string":n=!!t(r.depends,i.form).length;break;case"function":n=r.depends.call(i,i)}n?e[s]=void 0!==r.param?r.param:!0:delete e[s]}}),t.each(e,function(s,r){e[s]=t.isFunction(r)?r(i):r}),t.each(["minlength","maxlength"],function(){e[this]&&(e[this]=Number(e[this]))}),t.each(["rangelength","range"],function(){var i;e[this]&&(t.isArray(e[this])?e[this]=[Number(e[this][0]),Number(e[this][1])]:"string"==typeof e[this]&&(i=e[this].split(/[\s,]+/),e[this]=[Number(i[0]),Number(i[1])]))}),t.validator.autoCreateRanges&&(e.min&&e.max&&(e.range=[e.min,e.max],delete e.min,delete e.max),e.minlength&&e.maxlength&&(e.rangelength=[e.minlength,e.maxlength],delete e.minlength,delete e.maxlength)),e},normalizeRule:function(e){if("string"==typeof e){var i={};t.each(e.split(/\s/),function(){i[this]=!0}),e=i}return e},addMethod:function(e,i,s){t.validator.methods[e]=i,t.validator.messages[e]=void 0!==s?s:t.validator.messages[e],3>i.length&&t.validator.addClassRules(e,t.validator.normalizeRule(e))},methods:{required:function(e,i,s){if(!this.depend(s,i))return"dependency-mismatch";if("select"===i.nodeName.toLowerCase()){var r=t(i).val();return r&&r.length>0}return this.checkable(i)?this.getLength(e,i)>0:t.trim(e).length>0},email:function(t,e){return this.optional(e)||/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(t)},url:function(t,e){return this.optional(e)||/^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(t)},date:function(t,e){return this.optional(e)||!/Invalid|NaN/.test(""+new Date(t))},dateISO:function(t,e){return this.optional(e)||/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(t)},number:function(t,e){return this.optional(e)||/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(t)},digits:function(t,e){return this.optional(e)||/^\d+$/.test(t)},creditcard:function(t,e){if(this.optional(e))return"dependency-mismatch";if(/[^0-9 \-]+/.test(t))return!1;var i=0,s=0,r=!1;t=t.replace(/\D/g,"");for(var n=t.length-1;n>=0;n--){var a=t.charAt(n);s=parseInt(a,10),r&&(s*=2)>9&&(s-=9),i+=s,r=!r}return 0===i%10},minlength:function(e,i,s){var r=t.isArray(e)?e.length:this.getLength(t.trim(e),i);return this.optional(i)||r>=s},maxlength:function(e,i,s){var r=t.isArray(e)?e.length:this.getLength(t.trim(e),i);return this.optional(i)||s>=r},rangelength:function(e,i,s){var r=t.isArray(e)?e.length:this.getLength(t.trim(e),i);return this.optional(i)||r>=s[0]&&s[1]>=r},min:function(t,e,i){return this.optional(e)||t>=i},max:function(t,e,i){return this.optional(e)||i>=t},range:function(t,e,i){return this.optional(e)||t>=i[0]&&i[1]>=t},equalTo:function(e,i,s){var r=t(s);return this.settings.onfocusout&&r.unbind(".validate-equalTo").bind("blur.validate-equalTo",function(){t(i).valid()}),e===r.val()},remote:function(e,i,s){if(this.optional(i))return"dependency-mismatch";var r=this.previousValue(i);if(this.settings.messages[i.name]||(this.settings.messages[i.name]={}),r.originalMessage=this.settings.messages[i.name].remote,this.settings.messages[i.name].remote=r.message,s="string"==typeof s&&{url:s}||s,r.old===e)return r.valid;r.old=e;var n=this;this.startRequest(i);var a={};return a[i.name]=e,t.ajax(t.extend(!0,{url:s,mode:"abort",port:"validate"+i.name,dataType:"json",data:a,success:function(s){n.settings.messages[i.name].remote=r.originalMessage;var a=s===!0||"true"===s;if(a){var u=n.formSubmitted;n.prepareElement(i),n.formSubmitted=u,n.successList.push(i),delete n.invalid[i.name],n.showErrors()}else{var o={},l=s||n.defaultMessage(i,"remote");o[i.name]=r.message=t.isFunction(l)?l(e):l,n.invalid[i.name]=!0,n.showErrors(o)}r.valid=a,n.stopRequest(i,a)}},s)),"pending"}}}),t.format=t.validator.format})(jQuery),function(t){var e={};if(t.ajaxPrefilter)t.ajaxPrefilter(function(t,i,s){var r=t.port;"abort"===t.mode&&(e[r]&&e[r].abort(),e[r]=s)});else{var i=t.ajax;t.ajax=function(s){var r=("mode"in s?s:t.ajaxSettings).mode,n=("port"in s?s:t.ajaxSettings).port;return"abort"===r?(e[n]&&e[n].abort(),e[n]=i.apply(this,arguments),e[n]):i.apply(this,arguments)}}}(jQuery),function(t){t.extend(t.fn,{validateDelegate:function(e,i,s){return this.bind(i,function(i){var r=t(i.target);return r.is(e)?s.apply(r,arguments):void 0})}})}(jQuery); -------------------------------------------------------------------------------- /src/prismic.starter/Scripts/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | 16 | /** 17 | * bootstrap.js v3.0.0 by @fat and @mdo 18 | * Copyright 2013 Twitter Inc. 19 | * http://www.apache.org/licenses/LICENSE-2.0 20 | */ 21 | if(!jQuery)throw new Error("Bootstrap requires jQuery");+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]}}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one(a.support.transition.end,function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b()})}(window.jQuery),+function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype.close=function(b){function c(){f.trigger("closed.bs.alert").remove()}var d=a(this),e=d.attr("data-target");e||(e=d.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,""));var f=a(e);b&&b.preventDefault(),f.length||(f=d.hasClass("alert")?d:d.parent()),f.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one(a.support.transition.end,c).emulateTransitionEnd(150):c())};var d=a.fn.alert;a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("bs.alert");e||d.data("bs.alert",e=new c(this)),"string"==typeof b&&e[b].call(d)})},a.fn.alert.Constructor=c,a.fn.alert.noConflict=function(){return a.fn.alert=d,this},a(document).on("click.bs.alert.data-api",b,c.prototype.close)}(window.jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d)};b.DEFAULTS={loadingText:"loading..."},b.prototype.setState=function(a){var b="disabled",c=this.$element,d=c.is("input")?"val":"html",e=c.data();a+="Text",e.resetText||c.data("resetText",c[d]()),c[d](e[a]||this.options[a]),setTimeout(function(){"loadingText"==a?c.addClass(b).attr(b,b):c.removeClass(b).removeAttr(b)},0)},b.prototype.toggle=function(){var a=this.$element.closest('[data-toggle="buttons"]');if(a.length){var b=this.$element.find("input").prop("checked",!this.$element.hasClass("active")).trigger("change");"radio"===b.prop("type")&&a.find(".active").removeClass("active")}this.$element.toggleClass("active")};var c=a.fn.button;a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof c&&c;e||d.data("bs.button",e=new b(this,f)),"toggle"==c?e.toggle():c&&e.setState(c)})},a.fn.button.Constructor=b,a.fn.button.noConflict=function(){return a.fn.button=c,this},a(document).on("click.bs.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle"),b.preventDefault()})}(window.jQuery),+function(a){"use strict";var b=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,"hover"==this.options.pause&&this.$element.on("mouseenter",a.proxy(this.pause,this)).on("mouseleave",a.proxy(this.cycle,this))};b.DEFAULTS={interval:5e3,pause:"hover",wrap:!0},b.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},b.prototype.getActiveIndex=function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},b.prototype.to=function(b){var c=this,d=this.getActiveIndex();return b>this.$items.length-1||0>b?void 0:this.sliding?this.$element.one("slid",function(){c.to(b)}):d==b?this.pause().cycle():this.slide(b>d?"next":"prev",a(this.$items[b]))},b.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition.end&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},b.prototype.next=function(){return this.sliding?void 0:this.slide("next")},b.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},b.prototype.slide=function(b,c){var d=this.$element.find(".item.active"),e=c||d[b](),f=this.interval,g="next"==b?"left":"right",h="next"==b?"first":"last",i=this;if(!e.length){if(!this.options.wrap)return;e=this.$element.find(".item")[h]()}this.sliding=!0,f&&this.pause();var j=a.Event("slide.bs.carousel",{relatedTarget:e[0],direction:g});if(!e.hasClass("active")){if(this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid",function(){var b=a(i.$indicators.children()[i.getActiveIndex()]);b&&b.addClass("active")})),a.support.transition&&this.$element.hasClass("slide")){if(this.$element.trigger(j),j.isDefaultPrevented())return;e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),d.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid")},0)}).emulateTransitionEnd(600)}else{if(this.$element.trigger(j),j.isDefaultPrevented())return;d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return f&&this.cycle(),this}};var c=a.fn.carousel;a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c),g="string"==typeof c?c:f.slide;e||d.data("bs.carousel",e=new b(this,f)),"number"==typeof c?e.to(c):g?e[g]():f.interval&&e.pause().cycle()})},a.fn.carousel.Constructor=b,a.fn.carousel.noConflict=function(){return a.fn.carousel=c,this},a(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(b){var c,d=a(this),e=a(d.attr("data-target")||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"")),f=a.extend({},e.data(),d.data()),g=d.attr("data-slide-to");g&&(f.interval=!1),e.carousel(f),(g=d.attr("data-slide-to"))&&e.data("bs.carousel").to(g),b.preventDefault()}),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var b=a(this);b.carousel(b.data())})})}(window.jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.transitioning=null,this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.DEFAULTS={toggle:!0},b.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},b.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b=a.Event("show.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.$parent&&this.$parent.find("> .panel > .in");if(c&&c.length){var d=c.data("bs.collapse");if(d&&d.transitioning)return;c.collapse("hide"),d||c.data("bs.collapse",null)}var e=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[e](0),this.transitioning=1;var f=function(){this.$element.removeClass("collapsing").addClass("in")[e]("auto"),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return f.call(this);var g=a.camelCase(["scroll",e].join("-"));this.$element.one(a.support.transition.end,a.proxy(f,this)).emulateTransitionEnd(350)[e](this.$element[0][g])}}},b.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var d=function(){this.transitioning=0,this.$element.trigger("hidden.bs.collapse").removeClass("collapsing").addClass("collapse")};return a.support.transition?(this.$element[c](0).one(a.support.transition.end,a.proxy(d,this)).emulateTransitionEnd(350),void 0):d.call(this)}}},b.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};var c=a.fn.collapse;a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("bs.collapse"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c);e||d.data("bs.collapse",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.collapse.Constructor=b,a.fn.collapse.noConflict=function(){return a.fn.collapse=c,this},a(document).on("click.bs.collapse.data-api","[data-toggle=collapse]",function(b){var c,d=a(this),e=d.attr("data-target")||b.preventDefault()||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,""),f=a(e),g=f.data("bs.collapse"),h=g?"toggle":d.data(),i=d.attr("data-parent"),j=i&&a(i);g&&g.transitioning||(j&&j.find('[data-toggle=collapse][data-parent="'+i+'"]').not(d).addClass("collapsed"),d[f.hasClass("in")?"addClass":"removeClass"]("collapsed")),f.collapse(h)})}(window.jQuery),+function(a){"use strict";function b(){a(d).remove(),a(e).each(function(b){var d=c(a(this));d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown")),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown"))})}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}var d=".dropdown-backdrop",e="[data-toggle=dropdown]",f=function(b){a(b).on("click.bs.dropdown",this.toggle)};f.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){if("ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(''}),b.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),b.prototype.constructor=b,b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content")[this.options.html?"html":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},b.prototype.hasContent=function(){return this.getTitle()||this.getContent()},b.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},b.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var c=a.fn.popover;a.fn.popover=function(c){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof c&&c;e||d.data("bs.popover",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.popover.Constructor=b,a.fn.popover.noConflict=function(){return a.fn.popover=c,this}}(window.jQuery),+function(a){"use strict";function b(c,d){var e,f=a.proxy(this.process,this);this.$element=a(c).is("body")?a(window):a(c),this.$body=a("body"),this.$scrollElement=this.$element.on("scroll.bs.scroll-spy.data-api",f),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||(e=a(c).attr("href"))&&e.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.offsets=a([]),this.targets=a([]),this.activeTarget=null,this.refresh(),this.process()}b.DEFAULTS={offset:10},b.prototype.refresh=function(){var b=this.$element[0]==window?"offset":"position";this.offsets=a([]),this.targets=a([]);var c=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#\w/.test(e)&&a(e);return f&&f.length&&[[f[b]().top+(!a.isWindow(c.$scrollElement.get(0))&&c.$scrollElement.scrollTop()),e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){c.offsets.push(this[0]),c.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,d=c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(b>=d)return g!=(a=f.last()[0])&&this.activate(a);for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,a(this.selector).parents(".active").removeClass("active");var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate")};var c=a.fn.scrollspy;a.fn.scrollspy=function(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=c,this},a(window).on("load",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);b.scrollspy(b.data())})})}(window.jQuery),+function(a){"use strict";var b=function(b){this.element=a(b)};b.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.attr("data-target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a")[0],f=a.Event("show.bs.tab",{relatedTarget:e});if(b.trigger(f),!f.isDefaultPrevented()){var g=a(d);this.activate(b.parent("li"),c),this.activate(g,g.parent(),function(){b.trigger({type:"shown.bs.tab",relatedTarget:e})})}}},b.prototype.activate=function(b,c,d){function e(){f.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),g?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var f=c.find("> .active"),g=d&&a.support.transition&&f.hasClass("fade");g?f.one(a.support.transition.end,e).emulateTransitionEnd(150):e(),f.removeClass("in")};var c=a.fn.tab;a.fn.tab=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new b(this)),"string"==typeof c&&e[c]()})},a.fn.tab.Constructor=b,a.fn.tab.noConflict=function(){return a.fn.tab=c,this},a(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(b){b.preventDefault(),a(this).tab("show")})}(window.jQuery),+function(a){"use strict";var b=function(c,d){this.options=a.extend({},b.DEFAULTS,d),this.$window=a(window).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(c),this.affixed=this.unpin=null,this.checkPosition()};b.RESET="affix affix-top affix-bottom",b.DEFAULTS={offset:0},b.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},b.prototype.checkPosition=function(){if(this.$element.is(":visible")){var c=a(document).height(),d=this.$window.scrollTop(),e=this.$element.offset(),f=this.options.offset,g=f.top,h=f.bottom;"object"!=typeof f&&(h=g=f),"function"==typeof g&&(g=f.top()),"function"==typeof h&&(h=f.bottom());var i=null!=this.unpin&&d+this.unpin<=e.top?!1:null!=h&&e.top+this.$element.height()>=c-h?"bottom":null!=g&&g>=d?"top":!1;this.affixed!==i&&(this.unpin&&this.$element.css("top",""),this.affixed=i,this.unpin="bottom"==i?e.top-d:null,this.$element.removeClass(b.RESET).addClass("affix"+(i?"-"+i:"")),"bottom"==i&&this.$element.offset({top:document.body.offsetHeight-h-this.$element.height()}))}};var c=a.fn.affix;a.fn.affix=function(c){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof c&&c;e||d.data("bs.affix",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.affix.Constructor=b,a.fn.affix.noConflict=function(){return a.fn.affix=c,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var b=a(this),c=b.data();c.offset=c.offset||{},c.offsetBottom&&(c.offset.bottom=c.offsetBottom),c.offsetTop&&(c.offset.top=c.offsetTop),b.affix(c)})})}(window.jQuery); -------------------------------------------------------------------------------- /src/prismic.starter/Scripts/jquery.validate.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /*! 16 | * jQuery Validation Plugin 1.11.1 17 | * 18 | * http://bassistance.de/jquery-plugins/jquery-plugin-validation/ 19 | * http://docs.jquery.com/Plugins/Validation 20 | * 21 | * Copyright 2013 Jörn Zaefferer 22 | * Released under the MIT license: 23 | * http://www.opensource.org/licenses/mit-license.php 24 | */ 25 | 26 | (function($) { 27 | 28 | $.extend($.fn, { 29 | // http://docs.jquery.com/Plugins/Validation/validate 30 | validate: function( options ) { 31 | 32 | // if nothing is selected, return nothing; can't chain anyway 33 | if ( !this.length ) { 34 | if ( options && options.debug && window.console ) { 35 | console.warn( "Nothing selected, can't validate, returning nothing." ); 36 | } 37 | return; 38 | } 39 | 40 | // check if a validator for this form was already created 41 | var validator = $.data( this[0], "validator" ); 42 | if ( validator ) { 43 | return validator; 44 | } 45 | 46 | // Add novalidate tag if HTML5. 47 | this.attr( "novalidate", "novalidate" ); 48 | 49 | validator = new $.validator( options, this[0] ); 50 | $.data( this[0], "validator", validator ); 51 | 52 | if ( validator.settings.onsubmit ) { 53 | 54 | this.validateDelegate( ":submit", "click", function( event ) { 55 | if ( validator.settings.submitHandler ) { 56 | validator.submitButton = event.target; 57 | } 58 | // allow suppressing validation by adding a cancel class to the submit button 59 | if ( $(event.target).hasClass("cancel") ) { 60 | validator.cancelSubmit = true; 61 | } 62 | 63 | // allow suppressing validation by adding the html5 formnovalidate attribute to the submit button 64 | if ( $(event.target).attr("formnovalidate") !== undefined ) { 65 | validator.cancelSubmit = true; 66 | } 67 | }); 68 | 69 | // validate the form on submit 70 | this.submit( function( event ) { 71 | if ( validator.settings.debug ) { 72 | // prevent form submit to be able to see console output 73 | event.preventDefault(); 74 | } 75 | function handle() { 76 | var hidden; 77 | if ( validator.settings.submitHandler ) { 78 | if ( validator.submitButton ) { 79 | // insert a hidden input as a replacement for the missing submit button 80 | hidden = $("").attr("name", validator.submitButton.name).val( $(validator.submitButton).val() ).appendTo(validator.currentForm); 81 | } 82 | validator.settings.submitHandler.call( validator, validator.currentForm, event ); 83 | if ( validator.submitButton ) { 84 | // and clean up afterwards; thanks to no-block-scope, hidden can be referenced 85 | hidden.remove(); 86 | } 87 | return false; 88 | } 89 | return true; 90 | } 91 | 92 | // prevent submit for invalid forms or custom submit handlers 93 | if ( validator.cancelSubmit ) { 94 | validator.cancelSubmit = false; 95 | return handle(); 96 | } 97 | if ( validator.form() ) { 98 | if ( validator.pendingRequest ) { 99 | validator.formSubmitted = true; 100 | return false; 101 | } 102 | return handle(); 103 | } else { 104 | validator.focusInvalid(); 105 | return false; 106 | } 107 | }); 108 | } 109 | 110 | return validator; 111 | }, 112 | // http://docs.jquery.com/Plugins/Validation/valid 113 | valid: function() { 114 | if ( $(this[0]).is("form")) { 115 | return this.validate().form(); 116 | } else { 117 | var valid = true; 118 | var validator = $(this[0].form).validate(); 119 | this.each(function() { 120 | valid = valid && validator.element(this); 121 | }); 122 | return valid; 123 | } 124 | }, 125 | // attributes: space seperated list of attributes to retrieve and remove 126 | removeAttrs: function( attributes ) { 127 | var result = {}, 128 | $element = this; 129 | $.each(attributes.split(/\s/), function( index, value ) { 130 | result[value] = $element.attr(value); 131 | $element.removeAttr(value); 132 | }); 133 | return result; 134 | }, 135 | // http://docs.jquery.com/Plugins/Validation/rules 136 | rules: function( command, argument ) { 137 | var element = this[0]; 138 | 139 | if ( command ) { 140 | var settings = $.data(element.form, "validator").settings; 141 | var staticRules = settings.rules; 142 | var existingRules = $.validator.staticRules(element); 143 | switch(command) { 144 | case "add": 145 | $.extend(existingRules, $.validator.normalizeRule(argument)); 146 | // remove messages from rules, but allow them to be set separetely 147 | delete existingRules.messages; 148 | staticRules[element.name] = existingRules; 149 | if ( argument.messages ) { 150 | settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages ); 151 | } 152 | break; 153 | case "remove": 154 | if ( !argument ) { 155 | delete staticRules[element.name]; 156 | return existingRules; 157 | } 158 | var filtered = {}; 159 | $.each(argument.split(/\s/), function( index, method ) { 160 | filtered[method] = existingRules[method]; 161 | delete existingRules[method]; 162 | }); 163 | return filtered; 164 | } 165 | } 166 | 167 | var data = $.validator.normalizeRules( 168 | $.extend( 169 | {}, 170 | $.validator.classRules(element), 171 | $.validator.attributeRules(element), 172 | $.validator.dataRules(element), 173 | $.validator.staticRules(element) 174 | ), element); 175 | 176 | // make sure required is at front 177 | if ( data.required ) { 178 | var param = data.required; 179 | delete data.required; 180 | data = $.extend({required: param}, data); 181 | } 182 | 183 | return data; 184 | } 185 | }); 186 | 187 | // Custom selectors 188 | $.extend($.expr[":"], { 189 | // http://docs.jquery.com/Plugins/Validation/blank 190 | blank: function( a ) { return !$.trim("" + $(a).val()); }, 191 | // http://docs.jquery.com/Plugins/Validation/filled 192 | filled: function( a ) { return !!$.trim("" + $(a).val()); }, 193 | // http://docs.jquery.com/Plugins/Validation/unchecked 194 | unchecked: function( a ) { return !$(a).prop("checked"); } 195 | }); 196 | 197 | // constructor for validator 198 | $.validator = function( options, form ) { 199 | this.settings = $.extend( true, {}, $.validator.defaults, options ); 200 | this.currentForm = form; 201 | this.init(); 202 | }; 203 | 204 | $.validator.format = function( source, params ) { 205 | if ( arguments.length === 1 ) { 206 | return function() { 207 | var args = $.makeArray(arguments); 208 | args.unshift(source); 209 | return $.validator.format.apply( this, args ); 210 | }; 211 | } 212 | if ( arguments.length > 2 && params.constructor !== Array ) { 213 | params = $.makeArray(arguments).slice(1); 214 | } 215 | if ( params.constructor !== Array ) { 216 | params = [ params ]; 217 | } 218 | $.each(params, function( i, n ) { 219 | source = source.replace( new RegExp("\\{" + i + "\\}", "g"), function() { 220 | return n; 221 | }); 222 | }); 223 | return source; 224 | }; 225 | 226 | $.extend($.validator, { 227 | 228 | defaults: { 229 | messages: {}, 230 | groups: {}, 231 | rules: {}, 232 | errorClass: "error", 233 | validClass: "valid", 234 | errorElement: "label", 235 | focusInvalid: true, 236 | errorContainer: $([]), 237 | errorLabelContainer: $([]), 238 | onsubmit: true, 239 | ignore: ":hidden", 240 | ignoreTitle: false, 241 | onfocusin: function( element, event ) { 242 | this.lastActive = element; 243 | 244 | // hide error label and remove error class on focus if enabled 245 | if ( this.settings.focusCleanup && !this.blockFocusCleanup ) { 246 | if ( this.settings.unhighlight ) { 247 | this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass ); 248 | } 249 | this.addWrapper(this.errorsFor(element)).hide(); 250 | } 251 | }, 252 | onfocusout: function( element, event ) { 253 | if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) { 254 | this.element(element); 255 | } 256 | }, 257 | onkeyup: function( element, event ) { 258 | if ( event.which === 9 && this.elementValue(element) === "" ) { 259 | return; 260 | } else if ( element.name in this.submitted || element === this.lastElement ) { 261 | this.element(element); 262 | } 263 | }, 264 | onclick: function( element, event ) { 265 | // click on selects, radiobuttons and checkboxes 266 | if ( element.name in this.submitted ) { 267 | this.element(element); 268 | } 269 | // or option elements, check parent select in that case 270 | else if ( element.parentNode.name in this.submitted ) { 271 | this.element(element.parentNode); 272 | } 273 | }, 274 | highlight: function( element, errorClass, validClass ) { 275 | if ( element.type === "radio" ) { 276 | this.findByName(element.name).addClass(errorClass).removeClass(validClass); 277 | } else { 278 | $(element).addClass(errorClass).removeClass(validClass); 279 | } 280 | }, 281 | unhighlight: function( element, errorClass, validClass ) { 282 | if ( element.type === "radio" ) { 283 | this.findByName(element.name).removeClass(errorClass).addClass(validClass); 284 | } else { 285 | $(element).removeClass(errorClass).addClass(validClass); 286 | } 287 | } 288 | }, 289 | 290 | // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults 291 | setDefaults: function( settings ) { 292 | $.extend( $.validator.defaults, settings ); 293 | }, 294 | 295 | messages: { 296 | required: "This field is required.", 297 | remote: "Please fix this field.", 298 | email: "Please enter a valid email address.", 299 | url: "Please enter a valid URL.", 300 | date: "Please enter a valid date.", 301 | dateISO: "Please enter a valid date (ISO).", 302 | number: "Please enter a valid number.", 303 | digits: "Please enter only digits.", 304 | creditcard: "Please enter a valid credit card number.", 305 | equalTo: "Please enter the same value again.", 306 | maxlength: $.validator.format("Please enter no more than {0} characters."), 307 | minlength: $.validator.format("Please enter at least {0} characters."), 308 | rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."), 309 | range: $.validator.format("Please enter a value between {0} and {1}."), 310 | max: $.validator.format("Please enter a value less than or equal to {0}."), 311 | min: $.validator.format("Please enter a value greater than or equal to {0}.") 312 | }, 313 | 314 | autoCreateRanges: false, 315 | 316 | prototype: { 317 | 318 | init: function() { 319 | this.labelContainer = $(this.settings.errorLabelContainer); 320 | this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm); 321 | this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer ); 322 | this.submitted = {}; 323 | this.valueCache = {}; 324 | this.pendingRequest = 0; 325 | this.pending = {}; 326 | this.invalid = {}; 327 | this.reset(); 328 | 329 | var groups = (this.groups = {}); 330 | $.each(this.settings.groups, function( key, value ) { 331 | if ( typeof value === "string" ) { 332 | value = value.split(/\s/); 333 | } 334 | $.each(value, function( index, name ) { 335 | groups[name] = key; 336 | }); 337 | }); 338 | var rules = this.settings.rules; 339 | $.each(rules, function( key, value ) { 340 | rules[key] = $.validator.normalizeRule(value); 341 | }); 342 | 343 | function delegate(event) { 344 | var validator = $.data(this[0].form, "validator"), 345 | eventType = "on" + event.type.replace(/^validate/, ""); 346 | if ( validator.settings[eventType] ) { 347 | validator.settings[eventType].call(validator, this[0], event); 348 | } 349 | } 350 | $(this.currentForm) 351 | .validateDelegate(":text, [type='password'], [type='file'], select, textarea, " + 352 | "[type='number'], [type='search'] ,[type='tel'], [type='url'], " + 353 | "[type='email'], [type='datetime'], [type='date'], [type='month'], " + 354 | "[type='week'], [type='time'], [type='datetime-local'], " + 355 | "[type='range'], [type='color'] ", 356 | "focusin focusout keyup", delegate) 357 | .validateDelegate("[type='radio'], [type='checkbox'], select, option", "click", delegate); 358 | 359 | if ( this.settings.invalidHandler ) { 360 | $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler); 361 | } 362 | }, 363 | 364 | // http://docs.jquery.com/Plugins/Validation/Validator/form 365 | form: function() { 366 | this.checkForm(); 367 | $.extend(this.submitted, this.errorMap); 368 | this.invalid = $.extend({}, this.errorMap); 369 | if ( !this.valid() ) { 370 | $(this.currentForm).triggerHandler("invalid-form", [this]); 371 | } 372 | this.showErrors(); 373 | return this.valid(); 374 | }, 375 | 376 | checkForm: function() { 377 | this.prepareForm(); 378 | for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) { 379 | this.check( elements[i] ); 380 | } 381 | return this.valid(); 382 | }, 383 | 384 | // http://docs.jquery.com/Plugins/Validation/Validator/element 385 | element: function( element ) { 386 | element = this.validationTargetFor( this.clean( element ) ); 387 | this.lastElement = element; 388 | this.prepareElement( element ); 389 | this.currentElements = $(element); 390 | var result = this.check( element ) !== false; 391 | if ( result ) { 392 | delete this.invalid[element.name]; 393 | } else { 394 | this.invalid[element.name] = true; 395 | } 396 | if ( !this.numberOfInvalids() ) { 397 | // Hide error containers on last error 398 | this.toHide = this.toHide.add( this.containers ); 399 | } 400 | this.showErrors(); 401 | return result; 402 | }, 403 | 404 | // http://docs.jquery.com/Plugins/Validation/Validator/showErrors 405 | showErrors: function( errors ) { 406 | if ( errors ) { 407 | // add items to error list and map 408 | $.extend( this.errorMap, errors ); 409 | this.errorList = []; 410 | for ( var name in errors ) { 411 | this.errorList.push({ 412 | message: errors[name], 413 | element: this.findByName(name)[0] 414 | }); 415 | } 416 | // remove items from success list 417 | this.successList = $.grep( this.successList, function( element ) { 418 | return !(element.name in errors); 419 | }); 420 | } 421 | if ( this.settings.showErrors ) { 422 | this.settings.showErrors.call( this, this.errorMap, this.errorList ); 423 | } else { 424 | this.defaultShowErrors(); 425 | } 426 | }, 427 | 428 | // http://docs.jquery.com/Plugins/Validation/Validator/resetForm 429 | resetForm: function() { 430 | if ( $.fn.resetForm ) { 431 | $(this.currentForm).resetForm(); 432 | } 433 | this.submitted = {}; 434 | this.lastElement = null; 435 | this.prepareForm(); 436 | this.hideErrors(); 437 | this.elements().removeClass( this.settings.errorClass ).removeData( "previousValue" ); 438 | }, 439 | 440 | numberOfInvalids: function() { 441 | return this.objectLength(this.invalid); 442 | }, 443 | 444 | objectLength: function( obj ) { 445 | var count = 0; 446 | for ( var i in obj ) { 447 | count++; 448 | } 449 | return count; 450 | }, 451 | 452 | hideErrors: function() { 453 | this.addWrapper( this.toHide ).hide(); 454 | }, 455 | 456 | valid: function() { 457 | return this.size() === 0; 458 | }, 459 | 460 | size: function() { 461 | return this.errorList.length; 462 | }, 463 | 464 | focusInvalid: function() { 465 | if ( this.settings.focusInvalid ) { 466 | try { 467 | $(this.findLastActive() || this.errorList.length && this.errorList[0].element || []) 468 | .filter(":visible") 469 | .focus() 470 | // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find 471 | .trigger("focusin"); 472 | } catch(e) { 473 | // ignore IE throwing errors when focusing hidden elements 474 | } 475 | } 476 | }, 477 | 478 | findLastActive: function() { 479 | var lastActive = this.lastActive; 480 | return lastActive && $.grep(this.errorList, function( n ) { 481 | return n.element.name === lastActive.name; 482 | }).length === 1 && lastActive; 483 | }, 484 | 485 | elements: function() { 486 | var validator = this, 487 | rulesCache = {}; 488 | 489 | // select all valid inputs inside the form (no submit or reset buttons) 490 | return $(this.currentForm) 491 | .find("input, select, textarea") 492 | .not(":submit, :reset, :image, [disabled]") 493 | .not( this.settings.ignore ) 494 | .filter(function() { 495 | if ( !this.name && validator.settings.debug && window.console ) { 496 | console.error( "%o has no name assigned", this); 497 | } 498 | 499 | // select only the first element for each name, and only those with rules specified 500 | if ( this.name in rulesCache || !validator.objectLength($(this).rules()) ) { 501 | return false; 502 | } 503 | 504 | rulesCache[this.name] = true; 505 | return true; 506 | }); 507 | }, 508 | 509 | clean: function( selector ) { 510 | return $(selector)[0]; 511 | }, 512 | 513 | errors: function() { 514 | var errorClass = this.settings.errorClass.replace(" ", "."); 515 | return $(this.settings.errorElement + "." + errorClass, this.errorContext); 516 | }, 517 | 518 | reset: function() { 519 | this.successList = []; 520 | this.errorList = []; 521 | this.errorMap = {}; 522 | this.toShow = $([]); 523 | this.toHide = $([]); 524 | this.currentElements = $([]); 525 | }, 526 | 527 | prepareForm: function() { 528 | this.reset(); 529 | this.toHide = this.errors().add( this.containers ); 530 | }, 531 | 532 | prepareElement: function( element ) { 533 | this.reset(); 534 | this.toHide = this.errorsFor(element); 535 | }, 536 | 537 | elementValue: function( element ) { 538 | var type = $(element).attr("type"), 539 | val = $(element).val(); 540 | 541 | if ( type === "radio" || type === "checkbox" ) { 542 | return $("input[name='" + $(element).attr("name") + "']:checked").val(); 543 | } 544 | 545 | if ( typeof val === "string" ) { 546 | return val.replace(/\r/g, ""); 547 | } 548 | return val; 549 | }, 550 | 551 | check: function( element ) { 552 | element = this.validationTargetFor( this.clean( element ) ); 553 | 554 | var rules = $(element).rules(); 555 | var dependencyMismatch = false; 556 | var val = this.elementValue(element); 557 | var result; 558 | 559 | for (var method in rules ) { 560 | var rule = { method: method, parameters: rules[method] }; 561 | try { 562 | 563 | result = $.validator.methods[method].call( this, val, element, rule.parameters ); 564 | 565 | // if a method indicates that the field is optional and therefore valid, 566 | // don't mark it as valid when there are no other rules 567 | if ( result === "dependency-mismatch" ) { 568 | dependencyMismatch = true; 569 | continue; 570 | } 571 | dependencyMismatch = false; 572 | 573 | if ( result === "pending" ) { 574 | this.toHide = this.toHide.not( this.errorsFor(element) ); 575 | return; 576 | } 577 | 578 | if ( !result ) { 579 | this.formatAndAdd( element, rule ); 580 | return false; 581 | } 582 | } catch(e) { 583 | if ( this.settings.debug && window.console ) { 584 | console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e ); 585 | } 586 | throw e; 587 | } 588 | } 589 | if ( dependencyMismatch ) { 590 | return; 591 | } 592 | if ( this.objectLength(rules) ) { 593 | this.successList.push(element); 594 | } 595 | return true; 596 | }, 597 | 598 | // return the custom message for the given element and validation method 599 | // specified in the element's HTML5 data attribute 600 | customDataMessage: function( element, method ) { 601 | return $(element).data("msg-" + method.toLowerCase()) || (element.attributes && $(element).attr("data-msg-" + method.toLowerCase())); 602 | }, 603 | 604 | // return the custom message for the given element name and validation method 605 | customMessage: function( name, method ) { 606 | var m = this.settings.messages[name]; 607 | return m && (m.constructor === String ? m : m[method]); 608 | }, 609 | 610 | // return the first defined argument, allowing empty strings 611 | findDefined: function() { 612 | for(var i = 0; i < arguments.length; i++) { 613 | if ( arguments[i] !== undefined ) { 614 | return arguments[i]; 615 | } 616 | } 617 | return undefined; 618 | }, 619 | 620 | defaultMessage: function( element, method ) { 621 | return this.findDefined( 622 | this.customMessage( element.name, method ), 623 | this.customDataMessage( element, method ), 624 | // title is never undefined, so handle empty string as undefined 625 | !this.settings.ignoreTitle && element.title || undefined, 626 | $.validator.messages[method], 627 | "Warning: No message defined for " + element.name + "" 628 | ); 629 | }, 630 | 631 | formatAndAdd: function( element, rule ) { 632 | var message = this.defaultMessage( element, rule.method ), 633 | theregex = /\$?\{(\d+)\}/g; 634 | if ( typeof message === "function" ) { 635 | message = message.call(this, rule.parameters, element); 636 | } else if (theregex.test(message)) { 637 | message = $.validator.format(message.replace(theregex, "{$1}"), rule.parameters); 638 | } 639 | this.errorList.push({ 640 | message: message, 641 | element: element 642 | }); 643 | 644 | this.errorMap[element.name] = message; 645 | this.submitted[element.name] = message; 646 | }, 647 | 648 | addWrapper: function( toToggle ) { 649 | if ( this.settings.wrapper ) { 650 | toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) ); 651 | } 652 | return toToggle; 653 | }, 654 | 655 | defaultShowErrors: function() { 656 | var i, elements; 657 | for ( i = 0; this.errorList[i]; i++ ) { 658 | var error = this.errorList[i]; 659 | if ( this.settings.highlight ) { 660 | this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass ); 661 | } 662 | this.showLabel( error.element, error.message ); 663 | } 664 | if ( this.errorList.length ) { 665 | this.toShow = this.toShow.add( this.containers ); 666 | } 667 | if ( this.settings.success ) { 668 | for ( i = 0; this.successList[i]; i++ ) { 669 | this.showLabel( this.successList[i] ); 670 | } 671 | } 672 | if ( this.settings.unhighlight ) { 673 | for ( i = 0, elements = this.validElements(); elements[i]; i++ ) { 674 | this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass ); 675 | } 676 | } 677 | this.toHide = this.toHide.not( this.toShow ); 678 | this.hideErrors(); 679 | this.addWrapper( this.toShow ).show(); 680 | }, 681 | 682 | validElements: function() { 683 | return this.currentElements.not(this.invalidElements()); 684 | }, 685 | 686 | invalidElements: function() { 687 | return $(this.errorList).map(function() { 688 | return this.element; 689 | }); 690 | }, 691 | 692 | showLabel: function( element, message ) { 693 | var label = this.errorsFor( element ); 694 | if ( label.length ) { 695 | // refresh error/success class 696 | label.removeClass( this.settings.validClass ).addClass( this.settings.errorClass ); 697 | // replace message on existing label 698 | label.html(message); 699 | } else { 700 | // create label 701 | label = $("<" + this.settings.errorElement + ">") 702 | .attr("for", this.idOrName(element)) 703 | .addClass(this.settings.errorClass) 704 | .html(message || ""); 705 | if ( this.settings.wrapper ) { 706 | // make sure the element is visible, even in IE 707 | // actually showing the wrapped element is handled elsewhere 708 | label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent(); 709 | } 710 | if ( !this.labelContainer.append(label).length ) { 711 | if ( this.settings.errorPlacement ) { 712 | this.settings.errorPlacement(label, $(element) ); 713 | } else { 714 | label.insertAfter(element); 715 | } 716 | } 717 | } 718 | if ( !message && this.settings.success ) { 719 | label.text(""); 720 | if ( typeof this.settings.success === "string" ) { 721 | label.addClass( this.settings.success ); 722 | } else { 723 | this.settings.success( label, element ); 724 | } 725 | } 726 | this.toShow = this.toShow.add(label); 727 | }, 728 | 729 | errorsFor: function( element ) { 730 | var name = this.idOrName(element); 731 | return this.errors().filter(function() { 732 | return $(this).attr("for") === name; 733 | }); 734 | }, 735 | 736 | idOrName: function( element ) { 737 | return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name); 738 | }, 739 | 740 | validationTargetFor: function( element ) { 741 | // if radio/checkbox, validate first element in group instead 742 | if ( this.checkable(element) ) { 743 | element = this.findByName( element.name ).not(this.settings.ignore)[0]; 744 | } 745 | return element; 746 | }, 747 | 748 | checkable: function( element ) { 749 | return (/radio|checkbox/i).test(element.type); 750 | }, 751 | 752 | findByName: function( name ) { 753 | return $(this.currentForm).find("[name='" + name + "']"); 754 | }, 755 | 756 | getLength: function( value, element ) { 757 | switch( element.nodeName.toLowerCase() ) { 758 | case "select": 759 | return $("option:selected", element).length; 760 | case "input": 761 | if ( this.checkable( element) ) { 762 | return this.findByName(element.name).filter(":checked").length; 763 | } 764 | } 765 | return value.length; 766 | }, 767 | 768 | depend: function( param, element ) { 769 | return this.dependTypes[typeof param] ? this.dependTypes[typeof param](param, element) : true; 770 | }, 771 | 772 | dependTypes: { 773 | "boolean": function( param, element ) { 774 | return param; 775 | }, 776 | "string": function( param, element ) { 777 | return !!$(param, element.form).length; 778 | }, 779 | "function": function( param, element ) { 780 | return param(element); 781 | } 782 | }, 783 | 784 | optional: function( element ) { 785 | var val = this.elementValue(element); 786 | return !$.validator.methods.required.call(this, val, element) && "dependency-mismatch"; 787 | }, 788 | 789 | startRequest: function( element ) { 790 | if ( !this.pending[element.name] ) { 791 | this.pendingRequest++; 792 | this.pending[element.name] = true; 793 | } 794 | }, 795 | 796 | stopRequest: function( element, valid ) { 797 | this.pendingRequest--; 798 | // sometimes synchronization fails, make sure pendingRequest is never < 0 799 | if ( this.pendingRequest < 0 ) { 800 | this.pendingRequest = 0; 801 | } 802 | delete this.pending[element.name]; 803 | if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) { 804 | $(this.currentForm).submit(); 805 | this.formSubmitted = false; 806 | } else if (!valid && this.pendingRequest === 0 && this.formSubmitted) { 807 | $(this.currentForm).triggerHandler("invalid-form", [this]); 808 | this.formSubmitted = false; 809 | } 810 | }, 811 | 812 | previousValue: function( element ) { 813 | return $.data(element, "previousValue") || $.data(element, "previousValue", { 814 | old: null, 815 | valid: true, 816 | message: this.defaultMessage( element, "remote" ) 817 | }); 818 | } 819 | 820 | }, 821 | 822 | classRuleSettings: { 823 | required: {required: true}, 824 | email: {email: true}, 825 | url: {url: true}, 826 | date: {date: true}, 827 | dateISO: {dateISO: true}, 828 | number: {number: true}, 829 | digits: {digits: true}, 830 | creditcard: {creditcard: true} 831 | }, 832 | 833 | addClassRules: function( className, rules ) { 834 | if ( className.constructor === String ) { 835 | this.classRuleSettings[className] = rules; 836 | } else { 837 | $.extend(this.classRuleSettings, className); 838 | } 839 | }, 840 | 841 | classRules: function( element ) { 842 | var rules = {}; 843 | var classes = $(element).attr("class"); 844 | if ( classes ) { 845 | $.each(classes.split(" "), function() { 846 | if ( this in $.validator.classRuleSettings ) { 847 | $.extend(rules, $.validator.classRuleSettings[this]); 848 | } 849 | }); 850 | } 851 | return rules; 852 | }, 853 | 854 | attributeRules: function( element ) { 855 | var rules = {}; 856 | var $element = $(element); 857 | var type = $element[0].getAttribute("type"); 858 | 859 | for (var method in $.validator.methods) { 860 | var value; 861 | 862 | // support for in both html5 and older browsers 863 | if ( method === "required" ) { 864 | value = $element.get(0).getAttribute(method); 865 | // Some browsers return an empty string for the required attribute 866 | // and non-HTML5 browsers might have required="" markup 867 | if ( value === "" ) { 868 | value = true; 869 | } 870 | // force non-HTML5 browsers to return bool 871 | value = !!value; 872 | } else { 873 | value = $element.attr(method); 874 | } 875 | 876 | // convert the value to a number for number inputs, and for text for backwards compability 877 | // allows type="date" and others to be compared as strings 878 | if ( /min|max/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) { 879 | value = Number(value); 880 | } 881 | 882 | if ( value ) { 883 | rules[method] = value; 884 | } else if ( type === method && type !== 'range' ) { 885 | // exception: the jquery validate 'range' method 886 | // does not test for the html5 'range' type 887 | rules[method] = true; 888 | } 889 | } 890 | 891 | // maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs 892 | if ( rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength) ) { 893 | delete rules.maxlength; 894 | } 895 | 896 | return rules; 897 | }, 898 | 899 | dataRules: function( element ) { 900 | var method, value, 901 | rules = {}, $element = $(element); 902 | for (method in $.validator.methods) { 903 | value = $element.data("rule-" + method.toLowerCase()); 904 | if ( value !== undefined ) { 905 | rules[method] = value; 906 | } 907 | } 908 | return rules; 909 | }, 910 | 911 | staticRules: function( element ) { 912 | var rules = {}; 913 | var validator = $.data(element.form, "validator"); 914 | if ( validator.settings.rules ) { 915 | rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {}; 916 | } 917 | return rules; 918 | }, 919 | 920 | normalizeRules: function( rules, element ) { 921 | // handle dependency check 922 | $.each(rules, function( prop, val ) { 923 | // ignore rule when param is explicitly false, eg. required:false 924 | if ( val === false ) { 925 | delete rules[prop]; 926 | return; 927 | } 928 | if ( val.param || val.depends ) { 929 | var keepRule = true; 930 | switch (typeof val.depends) { 931 | case "string": 932 | keepRule = !!$(val.depends, element.form).length; 933 | break; 934 | case "function": 935 | keepRule = val.depends.call(element, element); 936 | break; 937 | } 938 | if ( keepRule ) { 939 | rules[prop] = val.param !== undefined ? val.param : true; 940 | } else { 941 | delete rules[prop]; 942 | } 943 | } 944 | }); 945 | 946 | // evaluate parameters 947 | $.each(rules, function( rule, parameter ) { 948 | rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter; 949 | }); 950 | 951 | // clean number parameters 952 | $.each(['minlength', 'maxlength'], function() { 953 | if ( rules[this] ) { 954 | rules[this] = Number(rules[this]); 955 | } 956 | }); 957 | $.each(['rangelength', 'range'], function() { 958 | var parts; 959 | if ( rules[this] ) { 960 | if ( $.isArray(rules[this]) ) { 961 | rules[this] = [Number(rules[this][0]), Number(rules[this][1])]; 962 | } else if ( typeof rules[this] === "string" ) { 963 | parts = rules[this].split(/[\s,]+/); 964 | rules[this] = [Number(parts[0]), Number(parts[1])]; 965 | } 966 | } 967 | }); 968 | 969 | if ( $.validator.autoCreateRanges ) { 970 | // auto-create ranges 971 | if ( rules.min && rules.max ) { 972 | rules.range = [rules.min, rules.max]; 973 | delete rules.min; 974 | delete rules.max; 975 | } 976 | if ( rules.minlength && rules.maxlength ) { 977 | rules.rangelength = [rules.minlength, rules.maxlength]; 978 | delete rules.minlength; 979 | delete rules.maxlength; 980 | } 981 | } 982 | 983 | return rules; 984 | }, 985 | 986 | // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true} 987 | normalizeRule: function( data ) { 988 | if ( typeof data === "string" ) { 989 | var transformed = {}; 990 | $.each(data.split(/\s/), function() { 991 | transformed[this] = true; 992 | }); 993 | data = transformed; 994 | } 995 | return data; 996 | }, 997 | 998 | // http://docs.jquery.com/Plugins/Validation/Validator/addMethod 999 | addMethod: function( name, method, message ) { 1000 | $.validator.methods[name] = method; 1001 | $.validator.messages[name] = message !== undefined ? message : $.validator.messages[name]; 1002 | if ( method.length < 3 ) { 1003 | $.validator.addClassRules(name, $.validator.normalizeRule(name)); 1004 | } 1005 | }, 1006 | 1007 | methods: { 1008 | 1009 | // http://docs.jquery.com/Plugins/Validation/Methods/required 1010 | required: function( value, element, param ) { 1011 | // check if dependency is met 1012 | if ( !this.depend(param, element) ) { 1013 | return "dependency-mismatch"; 1014 | } 1015 | if ( element.nodeName.toLowerCase() === "select" ) { 1016 | // could be an array for select-multiple or a string, both are fine this way 1017 | var val = $(element).val(); 1018 | return val && val.length > 0; 1019 | } 1020 | if ( this.checkable(element) ) { 1021 | return this.getLength(value, element) > 0; 1022 | } 1023 | return $.trim(value).length > 0; 1024 | }, 1025 | 1026 | // http://docs.jquery.com/Plugins/Validation/Methods/email 1027 | email: function( value, element ) { 1028 | // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/ 1029 | return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value); 1030 | }, 1031 | 1032 | // http://docs.jquery.com/Plugins/Validation/Methods/url 1033 | url: function( value, element ) { 1034 | // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/ 1035 | return this.optional(element) || /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value); 1036 | }, 1037 | 1038 | // http://docs.jquery.com/Plugins/Validation/Methods/date 1039 | date: function( value, element ) { 1040 | return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString()); 1041 | }, 1042 | 1043 | // http://docs.jquery.com/Plugins/Validation/Methods/dateISO 1044 | dateISO: function( value, element ) { 1045 | return this.optional(element) || /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(value); 1046 | }, 1047 | 1048 | // http://docs.jquery.com/Plugins/Validation/Methods/number 1049 | number: function( value, element ) { 1050 | return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value); 1051 | }, 1052 | 1053 | // http://docs.jquery.com/Plugins/Validation/Methods/digits 1054 | digits: function( value, element ) { 1055 | return this.optional(element) || /^\d+$/.test(value); 1056 | }, 1057 | 1058 | // http://docs.jquery.com/Plugins/Validation/Methods/creditcard 1059 | // based on http://en.wikipedia.org/wiki/Luhn 1060 | creditcard: function( value, element ) { 1061 | if ( this.optional(element) ) { 1062 | return "dependency-mismatch"; 1063 | } 1064 | // accept only spaces, digits and dashes 1065 | if ( /[^0-9 \-]+/.test(value) ) { 1066 | return false; 1067 | } 1068 | var nCheck = 0, 1069 | nDigit = 0, 1070 | bEven = false; 1071 | 1072 | value = value.replace(/\D/g, ""); 1073 | 1074 | for (var n = value.length - 1; n >= 0; n--) { 1075 | var cDigit = value.charAt(n); 1076 | nDigit = parseInt(cDigit, 10); 1077 | if ( bEven ) { 1078 | if ( (nDigit *= 2) > 9 ) { 1079 | nDigit -= 9; 1080 | } 1081 | } 1082 | nCheck += nDigit; 1083 | bEven = !bEven; 1084 | } 1085 | 1086 | return (nCheck % 10) === 0; 1087 | }, 1088 | 1089 | // http://docs.jquery.com/Plugins/Validation/Methods/minlength 1090 | minlength: function( value, element, param ) { 1091 | var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element); 1092 | return this.optional(element) || length >= param; 1093 | }, 1094 | 1095 | // http://docs.jquery.com/Plugins/Validation/Methods/maxlength 1096 | maxlength: function( value, element, param ) { 1097 | var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element); 1098 | return this.optional(element) || length <= param; 1099 | }, 1100 | 1101 | // http://docs.jquery.com/Plugins/Validation/Methods/rangelength 1102 | rangelength: function( value, element, param ) { 1103 | var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element); 1104 | return this.optional(element) || ( length >= param[0] && length <= param[1] ); 1105 | }, 1106 | 1107 | // http://docs.jquery.com/Plugins/Validation/Methods/min 1108 | min: function( value, element, param ) { 1109 | return this.optional(element) || value >= param; 1110 | }, 1111 | 1112 | // http://docs.jquery.com/Plugins/Validation/Methods/max 1113 | max: function( value, element, param ) { 1114 | return this.optional(element) || value <= param; 1115 | }, 1116 | 1117 | // http://docs.jquery.com/Plugins/Validation/Methods/range 1118 | range: function( value, element, param ) { 1119 | return this.optional(element) || ( value >= param[0] && value <= param[1] ); 1120 | }, 1121 | 1122 | // http://docs.jquery.com/Plugins/Validation/Methods/equalTo 1123 | equalTo: function( value, element, param ) { 1124 | // bind to the blur event of the target in order to revalidate whenever the target field is updated 1125 | // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead 1126 | var target = $(param); 1127 | if ( this.settings.onfocusout ) { 1128 | target.unbind(".validate-equalTo").bind("blur.validate-equalTo", function() { 1129 | $(element).valid(); 1130 | }); 1131 | } 1132 | return value === target.val(); 1133 | }, 1134 | 1135 | // http://docs.jquery.com/Plugins/Validation/Methods/remote 1136 | remote: function( value, element, param ) { 1137 | if ( this.optional(element) ) { 1138 | return "dependency-mismatch"; 1139 | } 1140 | 1141 | var previous = this.previousValue(element); 1142 | if (!this.settings.messages[element.name] ) { 1143 | this.settings.messages[element.name] = {}; 1144 | } 1145 | previous.originalMessage = this.settings.messages[element.name].remote; 1146 | this.settings.messages[element.name].remote = previous.message; 1147 | 1148 | param = typeof param === "string" && {url:param} || param; 1149 | 1150 | if ( previous.old === value ) { 1151 | return previous.valid; 1152 | } 1153 | 1154 | previous.old = value; 1155 | var validator = this; 1156 | this.startRequest(element); 1157 | var data = {}; 1158 | data[element.name] = value; 1159 | $.ajax($.extend(true, { 1160 | url: param, 1161 | mode: "abort", 1162 | port: "validate" + element.name, 1163 | dataType: "json", 1164 | data: data, 1165 | success: function( response ) { 1166 | validator.settings.messages[element.name].remote = previous.originalMessage; 1167 | var valid = response === true || response === "true"; 1168 | if ( valid ) { 1169 | var submitted = validator.formSubmitted; 1170 | validator.prepareElement(element); 1171 | validator.formSubmitted = submitted; 1172 | validator.successList.push(element); 1173 | delete validator.invalid[element.name]; 1174 | validator.showErrors(); 1175 | } else { 1176 | var errors = {}; 1177 | var message = response || validator.defaultMessage( element, "remote" ); 1178 | errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message; 1179 | validator.invalid[element.name] = true; 1180 | validator.showErrors(errors); 1181 | } 1182 | previous.valid = valid; 1183 | validator.stopRequest(element, valid); 1184 | } 1185 | }, param)); 1186 | return "pending"; 1187 | } 1188 | 1189 | } 1190 | 1191 | }); 1192 | 1193 | // deprecated, use $.validator.format instead 1194 | $.format = $.validator.format; 1195 | 1196 | }(jQuery)); 1197 | 1198 | // ajax mode: abort 1199 | // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); 1200 | // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() 1201 | (function($) { 1202 | var pendingRequests = {}; 1203 | // Use a prefilter if available (1.5+) 1204 | if ( $.ajaxPrefilter ) { 1205 | $.ajaxPrefilter(function( settings, _, xhr ) { 1206 | var port = settings.port; 1207 | if ( settings.mode === "abort" ) { 1208 | if ( pendingRequests[port] ) { 1209 | pendingRequests[port].abort(); 1210 | } 1211 | pendingRequests[port] = xhr; 1212 | } 1213 | }); 1214 | } else { 1215 | // Proxy ajax 1216 | var ajax = $.ajax; 1217 | $.ajax = function( settings ) { 1218 | var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode, 1219 | port = ( "port" in settings ? settings : $.ajaxSettings ).port; 1220 | if ( mode === "abort" ) { 1221 | if ( pendingRequests[port] ) { 1222 | pendingRequests[port].abort(); 1223 | } 1224 | pendingRequests[port] = ajax.apply(this, arguments); 1225 | return pendingRequests[port]; 1226 | } 1227 | return ajax.apply(this, arguments); 1228 | }; 1229 | } 1230 | }(jQuery)); 1231 | 1232 | // provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation 1233 | // handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target 1234 | (function($) { 1235 | $.extend($.fn, { 1236 | validateDelegate: function( delegate, type, handler ) { 1237 | return this.bind(type, function( event ) { 1238 | var target = $(event.target); 1239 | if ( target.is(delegate) ) { 1240 | return handler.apply(target, arguments); 1241 | } 1242 | }); 1243 | } 1244 | }); 1245 | }(jQuery)); 1246 | --------------------------------------------------------------------------------