Esempio n. 1
0
        private ResourceDefinition FindResource(RequireSettings settings, bool resolveInlineDefinitions)
        {
            // find the resource with the given type and name
            // that has at least the given version number. If multiple,
            // return the resource with the greatest version number.
            // If not found and an inlineDefinition is given, define the resource on the fly
            // using the action.
            var name = settings.Name ?? "";
            var type = settings.Type;

            var stream   = ResourceManifests.SelectMany(x => x.GetResources(type));
            var resource = FindMatchingResource(stream, settings, name);

            if (resource == null && _dynamicManifest != null)
            {
                stream   = _dynamicManifest.GetResources(type);
                resource = FindMatchingResource(stream, settings, name);
            }

            if (resolveInlineDefinitions && resource == null)
            {
                // Does not seem to exist, but it's possible it is being
                // defined by a Define() from a RequireSettings somewhere.
                if (ResolveInlineDefinitions(settings.Type))
                {
                    // if any were defined, now try to find it
                    resource = FindResource(settings, false);
                }
            }

            return(resource);
        }
Esempio n. 2
0
        public RequireSettings RegisterResource(string resourceType, string resourceName)
        {
            if (resourceType == null)
            {
                return(ThrowArgumentNullException <RequireSettings>(nameof(resourceType)));
            }

            if (resourceName == null)
            {
                return(ThrowArgumentNullException <RequireSettings>(nameof(resourceName)));
            }

            var key = new ResourceTypeName(resourceType, resourceName);

            if (!_required.TryGetValue(key, out var settings))
            {
                settings = new RequireSettings(_options)
                {
                    Type = resourceType,
                    Name = resourceName
                };
                _required[key] = settings;
            }
            _builtResources[resourceType] = null;
            return(settings);
        }
Esempio n. 3
0
        public void AddExpandingResource(ResourceDefinition resource, RequireSettings settings)
        {
            if (_expanding.Contains(resource))
            {
                throw new InvalidOperationException($"Circular dependency of type '{settings.Type}' detected between '{settings.Name}' and '{resource.Name}'");
            }

            _expanding.Push(resource);
        }
Esempio n. 4
0
        protected virtual void ExpandDependencies(
            ResourceDefinition resource,
            RequireSettings settings,
            OrderedDictionary allResources)
        {
            if (resource == null)
            {
                return;
            }

            // Settings is given so they can cascade down into dependencies. For example, if Foo depends on Bar, and Foo's required
            // location is Head, so too should Bar's location.
            // forge the effective require settings for this resource
            // (1) If a require exists for the resource, combine with it. Last settings in gets preference for its specified values.
            // (2) If no require already exists, form a new settings object based on the given one but with its own type/name.
            settings = allResources.Contains(resource)
                ? ((RequireSettings)allResources[resource]).Combine(settings)
                : new RequireSettings(_options)
            {
                Type = resource.Type, Name = resource.Name
            }.Combine(settings);

            if (resource.Dependencies != null)
            {
                // share search instance
                var tempSettings = new RequireSettings();

                for (var i = 0; i < resource.Dependencies.Count; i++)
                {
                    var    d       = resource.Dependencies[i];
                    var    idx     = d.IndexOf(':');
                    var    name    = d;
                    string version = null;
                    if (idx != -1)
                    {
                        name    = d.Substring(0, idx);
                        version = d.Substring(idx + 1);
                    }

                    tempSettings.Type    = resource.Type;
                    tempSettings.Name    = name;
                    tempSettings.Version = version;

                    var dependency = FindResource(tempSettings);
                    if (dependency == null)
                    {
                        continue;
                    }

                    ExpandDependencies(dependency, settings, allResources);
                }
            }
            allResources[resource] = settings;
        }
Esempio n. 5
0
        private ResourceDefinition FindMatchingResource(
            IEnumerable <KeyValuePair <string, IList <ResourceDefinition> > > stream,
            RequireSettings settings,
            string type,
            string name)
        {
            Version lower = null;
            Version upper = null;

            if (!String.IsNullOrEmpty(settings.Version))
            {
                // Specific version, filter
                lower = GetLowerBoundVersion(settings.Version);
                upper = GetUpperBoundVersion(settings.Version);
            }

            ResourceDefinition resource = null;

            foreach (var r in stream)
            {
                if (String.Equals(r.Key, name, StringComparison.OrdinalIgnoreCase))
                {
                    foreach (var resourceDefinition in r.Value)
                    {
                        var version = resourceDefinition.Version != null
                            ? new Version(resourceDefinition.Version)
                            : null;

                        if (lower != null)
                        {
                            if (lower > version || version >= upper)
                            {
                                continue;
                            }
                        }

                        // Use the highest version of all matches
                        if (resource == null ||
                            (resourceDefinition.Version != null && new Version(resource.Version) < version))
                        {
                            resource = resourceDefinition;
                        }
                    }
                }
            }

            return(resource);
        }
        public void RenderStylesheet(IHtmlContentBuilder builder, RequireSettings settings)
        {
            var first = true;

            var styleSheets = this.GetRequiredResources("stylesheet");

            foreach (var context in styleSheets)
            {
                if (!first)
                {
                    builder.AppendHtml(Environment.NewLine);
                }

                first = false;

                builder.AppendHtml(context.GetHtmlContent(settings, "/"));
            }
        }
Esempio n. 7
0
        public RequireSettings Combine(RequireSettings other)
        {
            var settings = (new RequireSettings
            {
                Name = Name,
                Type = Type
            }).AtLocation(Location).AtLocation(other.Location)
                           .WithBasePath(BasePath).WithBasePath(other.BasePath)
                           .UseCdn(CdnMode).UseCdn(other.CdnMode)
                           .UseDebugMode(DebugMode).UseDebugMode(other.DebugMode)
                           .UseCulture(Culture).UseCulture(other.Culture)
                           .UseCondition(Condition).UseCondition(other.Condition)
                           .UseVersion(Version).UseVersion(other.Version)
                           .Define(InlineDefinition).Define(other.InlineDefinition);

            settings._attributes = MergeAttributes(other);
            return(settings);
        }
Esempio n. 8
0
        private Dictionary <string, string> MergeAttributes(RequireSettings other)
        {
            // efficiently merge the two dictionaries, taking into account that one or both may not exist
            // and that attributes in 'other' should overridde attributes in this, even if the value is null.
            if (_attributes == null)
            {
                return(other._attributes == null ? null : new Dictionary <string, string>(other._attributes));
            }
            if (other._attributes == null)
            {
                return(new Dictionary <string, string>(_attributes));
            }
            var mergedAttributes = new Dictionary <string, string>(_attributes);

            foreach (var pair in other._attributes)
            {
                mergedAttributes[pair.Key] = pair.Value;
            }
            return(mergedAttributes);
        }
        public void RenderLocalScript(RequireSettings settings, IHtmlContentBuilder builder)
        {
            var localScripts = this.GetRequiredResources("script");

            var first = true;

            foreach (var context in localScripts.Where(r => r.Settings.Location == ResourceLocation.Unspecified))
            {
                if (_localScripts.Add(context.Settings.Name) || context.Settings.Name == settings.Name)
                {
                    if (!first)
                    {
                        builder.AppendHtml(Environment.NewLine);
                    }

                    first = false;

                    builder.AppendHtml(context.GetHtmlContent(_pathBase));
                }
            }
        }
Esempio n. 10
0
        public void RenderLocalScript(RequireSettings settings, IHtmlContentBuilder builder)
        {
            var localScripts = DoGetRequiredResources("script");

            var first = true;

            foreach (var context in localScripts)
            {
                if (context.Settings.Location == ResourceLocation.Unspecified &&
                    (_localScripts.Add(context.Settings.Name) || context.Settings.Name == settings.Name))
                {
                    if (!first)
                    {
                        builder.AppendHtml(System.Environment.NewLine);
                    }

                    first = false;

                    builder.AppendHtml(context.GetHtmlContent(_options.ContentBasePath));
                }
            }
        }
Esempio n. 11
0
        public IHtmlContent GetHtmlContent(RequireSettings baseSettings, string appPath)
        {
            var combinedSettings = baseSettings == null ? Settings : baseSettings.Combine(Settings);

            var tagBuilder = Resource.GetTagBuilder(combinedSettings, appPath);

            if (String.IsNullOrEmpty(combinedSettings.Condition))
            {
                return(tagBuilder);
            }

            var builder = new HtmlContentBuilder();

            if (combinedSettings.Condition == NotIE)
            {
                builder.AppendHtml("<!--[if " + combinedSettings.Condition + "]>-->");
            }
            else
            {
                builder.AppendHtml("<!--[if " + combinedSettings.Condition + "]>");
            }

            builder.AppendHtml(tagBuilder);

            if (!string.IsNullOrEmpty(combinedSettings.Condition))
            {
                if (combinedSettings.Condition == NotIE)
                {
                    builder.AppendHtml("<!--<![endif]-->");
                }
                else
                {
                    builder.AppendHtml("<![endif]-->");
                }
            }

            return(builder);
        }
Esempio n. 12
0
        public void AddExpandedResource(ResourceDefinition resource, RequireSettings settings)
        {
            _expanding.Pop();

            if (settings.Position != ResourcePosition.ByDependency)
            {
                var existing = (RequireSettings)this[resource];
                if (existing == null || existing.Position == ResourcePosition.ByDependency)
                {
                    if (settings.Position == ResourcePosition.First)
                    {
                        FirstCount++;
                    }

                    if (settings.Position == ResourcePosition.Last)
                    {
                        LastCount++;
                    }
                }
            }

            this[resource] = settings;
        }
Esempio n. 13
0
        protected virtual void ExpandDependencies(ResourceDefinition resource, RequireSettings settings, OrderedDictionary allResources)
        {
            if (resource == null)
            {
                return;
            }
            // Settings is given so they can cascade down into dependencies. For example, if Foo depends on Bar, and Foo's required
            // location is Head, so too should Bar's location.
            // forge the effective require settings for this resource
            // (1) If a require exists for the resource, combine with it. Last settings in gets preference for its specified values.
            // (2) If no require already exists, form a new settings object based on the given one but with its own type/name.
            settings = allResources.Contains(resource)
                ? ((RequireSettings)allResources[resource]).Combine(settings)
                : new RequireSettings(_options.Value)
            {
                Type = resource.Type, Name = resource.Name
            }.Combine(settings);
            if (resource.Dependencies != null)
            {
                var dependencies = from d in resource.Dependencies
                                   let segments                       = d.Split(':')
                                                             let name = segments[0]
                                                                        let version = segments.Length > 1 ? segments[1] : null
                                                                                      select FindResource(new RequireSettings { Type = resource.Type, Name = name, Version = version });

                foreach (var dependency in dependencies)
                {
                    if (dependency == null)
                    {
                        continue;
                    }
                    ExpandDependencies(dependency, settings, allResources);
                }
            }
            allResources[resource] = settings;
        }
Esempio n. 14
0
        protected virtual void ExpandDependencies(
            ResourceDefinition resource,
            RequireSettings settings,
            ResourceDictionary allResources)
        {
            if (resource == null)
            {
                return;
            }

            allResources.AddExpandingResource(resource, settings);

            // Use any additional dependencies from the settings without mutating the resource that is held in a singleton collection.
            List <string> dependencies = null;

            if (resource.Dependencies != null)
            {
                dependencies = new List <string>(resource.Dependencies);
                if (settings.Dependencies != null)
                {
                    dependencies.AddRange(settings.Dependencies);
                }
            }
            else if (settings.Dependencies != null)
            {
                dependencies = new List <string>(settings.Dependencies);
            }

            // Settings is given so they can cascade down into dependencies. For example, if Foo depends on Bar, and Foo's required
            // location is Head, so too should Bar's location, similarly, if Foo is First positioned, Bar dependency should be too.
            //
            // forge the effective require settings for this resource
            // (1) If a require exists for the resource, combine with it. Last settings in gets preference for its specified values.
            // (2) If no require already exists, form a new settings object based on the given one but with its own type/name.

            var dependencySettings = (((RequireSettings)allResources[resource])
                                      ?.NewAndCombine(settings)
                                      ?? new RequireSettings(_options)
            {
                Name = resource.Name,
                Type = resource.Type,
                Position = resource.Position
            }
                                      .Combine(settings))
                                     .CombinePosition(settings)
            ;

            if (dependencies != null)
            {
                // share search instance
                var tempSettings = new RequireSettings();

                for (var i = 0; i < dependencies.Count; i++)
                {
                    var    d       = dependencies[i];
                    var    idx     = d.IndexOf(':');
                    var    name    = d;
                    string version = null;
                    if (idx != -1)
                    {
                        name    = d.Substring(0, idx);
                        version = d[(idx + 1)..];
Esempio n. 15
0
        public TagBuilder GetTagBuilder(RequireSettings settings, string applicationPath)
        {
            string url;
            // Url priority:
            if (settings.DebugMode)
            {
                url = settings.CdnMode
                    ? Coalesce(UrlCdnDebug, UrlDebug, UrlCdn, Url)
                    : Coalesce(UrlDebug, Url, UrlCdnDebug, UrlCdn);
            }
            else
            {
                url = settings.CdnMode
                    ? Coalesce(UrlCdn, Url, UrlCdnDebug, UrlDebug)
                    : Coalesce(Url, UrlDebug, UrlCdn, UrlCdnDebug);
            }
            if (String.IsNullOrEmpty(url))
            {
                url = null;
            }
            if (!String.IsNullOrEmpty(settings.Culture))
            {
                string nearestCulture = FindNearestCulture(settings.Culture);
                if (!String.IsNullOrEmpty(nearestCulture))
                {
                    url = Path.ChangeExtension(url, nearestCulture + Path.GetExtension(url));
                }
            }

            if (url.StartsWith("~/", StringComparison.Ordinal))
            {
                if (!String.IsNullOrEmpty(_basePath))
                {
                    url = _basePath + url.Substring(1);
                }
                else
                {
                    url = applicationPath + url.Substring(1);
                }
                
            }

            var tagBuilder = new TagBuilder(TagName)
            {
                TagRenderMode = TagRenderMode
            };

            if (!String.IsNullOrEmpty(CdnIntegrity) && url != null && url == UrlCdn)
            {
                tagBuilder.Attributes["integrity"] = CdnIntegrity;
                tagBuilder.Attributes["crossorigin"] = "anonymous";
            }
            else if (!String.IsNullOrEmpty(CdnDebugIntegrity) && url != null && url == UrlCdnDebug)
            {
                tagBuilder.Attributes["integrity"] = CdnDebugIntegrity;
                tagBuilder.Attributes["crossorigin"] = "anonymous";
            }

            if (_resourceAttributes.ContainsKey(Type))
            {
                tagBuilder.MergeAttributes(_resourceAttributes[Type]);
            }

            if (Attributes != null)
            {
                tagBuilder.MergeAttributes(Attributes);
            }

            if (settings.HasAttributes)
            {
                tagBuilder.MergeAttributes(settings.Attributes);
            }

            if (!String.IsNullOrEmpty(FilePathAttributeName))
            {
                if (!String.IsNullOrEmpty(url))
                {
                    tagBuilder.MergeAttribute(FilePathAttributeName, url, true);
                }
            }

            return tagBuilder;
        }
        private ResourceDefinition FindResource(RequireSettings settings, bool resolveInlineDefinitions)
        {
            // find the resource with the given type and name
            // that has at least the given version number. If multiple,
            // return the resource with the greatest version number.
            // If not found and an inlineDefinition is given, define the resource on the fly
            // using the action.
            var name = settings.Name ?? "";
            var type = settings.Type;
            ResourceDefinition resource;

            var resources = (from p in ResourceManifests
                             from r in p.GetResources(type)
                             where name.Equals(r.Key, StringComparison.OrdinalIgnoreCase)
                             select r.Value).SelectMany(x => x);

            if (!String.IsNullOrEmpty(settings.Version))
            {
                // Specific version, filter
                var upper = GetUpperBoundVersion(settings.Version);
                var lower = GetLowerBoundVersion(settings.Version);
                resources = from r in resources
                            let version = r.Version != null ? new Version(r.Version) : null
                                          where lower <= version && version < upper
                                          select r;
            }

            // Use the highest version of all matches
            resource = (from r in resources
                        let version = r.Version != null ? new Version(r.Version) : null
                                      orderby version descending
                                      select r).FirstOrDefault();

            if (resource == null && _dynamicManifest != null)
            {
                resources = (from r in _dynamicManifest.GetResources(type)
                             where name.Equals(r.Key, StringComparison.OrdinalIgnoreCase)
                             select r.Value).SelectMany(x => x);

                if (!String.IsNullOrEmpty(settings.Version))
                {
                    // Specific version, filter
                    var upper = GetUpperBoundVersion(settings.Version);
                    var lower = GetLowerBoundVersion(settings.Version);
                    resources = from r in resources
                                let version = r.Version != null ? new Version(r.Version) : null
                                              where lower <= version && version < upper
                                              select r;
                }

                // Use the highest version of all matches
                resource = (from r in resources
                            let version = r.Version != null ? new Version(r.Version) : null
                                          orderby version descending
                                          select r).FirstOrDefault();
            }

            if (resolveInlineDefinitions && resource == null)
            {
                // Does not seem to exist, but it's possible it is being
                // defined by a Define() from a RequireSettings somewhere.
                if (ResolveInlineDefinitions(settings.Type))
                {
                    // if any were defined, now try to find it
                    resource = FindResource(settings, false);
                }
            }

            return(resource);
        }
 public ResourceDefinition FindResource(RequireSettings settings)
 {
     return(FindResource(settings, true));
 }
        public TagBuilder GetTagBuilder(RequireSettings settings,
                                        string applicationPath,
                                        IFileVersionProvider fileVersionProvider)
        {
            string url;

            // Url priority:
            if (settings.DebugMode)
            {
                url = settings.CdnMode
                    ? Coalesce(UrlCdnDebug, UrlDebug, UrlCdn, Url)
                    : Coalesce(UrlDebug, Url, UrlCdnDebug, UrlCdn);
            }
            else
            {
                url = settings.CdnMode
                    ? Coalesce(UrlCdn, Url, UrlCdnDebug, UrlDebug)
                    : Coalesce(Url, UrlDebug, UrlCdn, UrlCdnDebug);
            }

            if (String.IsNullOrEmpty(url))
            {
                url = null;
            }
            if (!String.IsNullOrEmpty(settings.Culture))
            {
                string nearestCulture = FindNearestCulture(settings.Culture);
                if (!String.IsNullOrEmpty(nearestCulture))
                {
                    url = Path.ChangeExtension(url, nearestCulture + Path.GetExtension(url));
                }
            }

            if (url.StartsWith("~/", StringComparison.Ordinal))
            {
                if (!String.IsNullOrEmpty(_basePath))
                {
                    url = _basePath + url.Substring(1);
                }
                else
                {
                    url = applicationPath + url.Substring(1);
                }
            }

            // If settings has value, it can override resource definition, otherwise use resource definition
            if (url != null && ((settings.AppendVersion.HasValue && settings.AppendVersion == true) ||
                                (!settings.AppendVersion.HasValue && AppendVersion == true)))
            {
                url = fileVersionProvider.AddFileVersionToPath(applicationPath, url);
            }

            // Don't prefix cdn if the path is absolute, or is in debug mode.
            if (!settings.DebugMode &&
                !String.IsNullOrEmpty(settings.CdnBaseUrl) &&
                !Uri.TryCreate(url, UriKind.Absolute, out var uri))
            {
                url = settings.CdnBaseUrl + url;
            }

            var tagBuilder = new TagBuilder(TagName)
            {
                TagRenderMode = TagRenderMode
            };

            if (!String.IsNullOrEmpty(CdnIntegrity) && url != null && url == UrlCdn)
            {
                tagBuilder.Attributes["integrity"]   = CdnIntegrity;
                tagBuilder.Attributes["crossorigin"] = "anonymous";
            }
            else if (!String.IsNullOrEmpty(CdnDebugIntegrity) && url != null && url == UrlCdnDebug)
            {
                tagBuilder.Attributes["integrity"]   = CdnDebugIntegrity;
                tagBuilder.Attributes["crossorigin"] = "anonymous";
            }

            if (_resourceAttributes.ContainsKey(Type))
            {
                tagBuilder.MergeAttributes(_resourceAttributes[Type]);
            }

            if (Attributes != null)
            {
                tagBuilder.MergeAttributes(Attributes);
            }

            if (settings.HasAttributes)
            {
                tagBuilder.MergeAttributes(settings.Attributes);
            }

            if (!String.IsNullOrEmpty(FilePathAttributeName))
            {
                if (!String.IsNullOrEmpty(url))
                {
                    tagBuilder.MergeAttribute(FilePathAttributeName, url, true);
                }
            }

            return(tagBuilder);
        }
        public TagBuilder GetTagBuilder(RequireSettings settings,
                                        string applicationPath,
                                        IFileVersionProvider fileVersionProvider)
        {
            string url, filePathAttributeName = null;

            // Url priority:
            if (settings.DebugMode)
            {
                url = settings.CdnMode
                    ? Coalesce(UrlCdnDebug, UrlDebug, UrlCdn, Url)
                    : Coalesce(UrlDebug, Url, UrlCdnDebug, UrlCdn);
            }
            else
            {
                url = settings.CdnMode
                    ? Coalesce(UrlCdn, Url, UrlCdnDebug, UrlDebug)
                    : Coalesce(Url, UrlDebug, UrlCdn, UrlCdnDebug);
            }

            if (String.IsNullOrEmpty(url))
            {
                url = null;
            }
            if (!String.IsNullOrEmpty(settings.Culture))
            {
                string nearestCulture = FindNearestCulture(settings.Culture);
                if (!String.IsNullOrEmpty(nearestCulture))
                {
                    url = Path.ChangeExtension(url, nearestCulture + Path.GetExtension(url));
                }
            }

            if (url != null && url.StartsWith("~/", StringComparison.Ordinal))
            {
                if (!String.IsNullOrEmpty(_basePath))
                {
                    url = _basePath + url.Substring(1);
                }
                else
                {
                    url = applicationPath + url.Substring(1);
                }
            }

            // If settings has value, it can override resource definition, otherwise use resource definition
            if (url != null && ((settings.AppendVersion.HasValue && settings.AppendVersion == true) ||
                                (!settings.AppendVersion.HasValue && AppendVersion == true)))
            {
                url = fileVersionProvider.AddFileVersionToPath(applicationPath, url);
            }

            // Don't prefix cdn if the path is absolute, or is in debug mode.
            if (!settings.DebugMode &&
                !String.IsNullOrEmpty(settings.CdnBaseUrl) &&
                !Uri.TryCreate(url, UriKind.Absolute, out var uri))
            {
                url = settings.CdnBaseUrl + url;
            }

            TagBuilder tagBuilder;

            switch (Type)
            {
            case "script":
                tagBuilder            = new TagBuilder("script");
                filePathAttributeName = "src";
                break;

            case "stylesheet":
                if (url == null && InnerContent != null)
                {
                    // Inline style declaration
                    tagBuilder = new TagBuilder("style")
                    {
                        Attributes =
                        {
                            { "type", "text/css" }
                        }
                    };
                }
                else
                {
                    // Stylesheet resource
                    tagBuilder = new TagBuilder("link")
                    {
                        TagRenderMode = TagRenderMode.SelfClosing,
                        Attributes    =
                        {
                            { "type", "text/css"   },
                            { "rel",  "stylesheet" }
                        }
                    };
                    filePathAttributeName = "href";
                }
                break;

            case "link":
                tagBuilder = new TagBuilder("link")
                {
                    TagRenderMode = TagRenderMode.SelfClosing
                };
                filePathAttributeName = "href";
                break;

            default:
                tagBuilder = new TagBuilder("meta")
                {
                    TagRenderMode = TagRenderMode.SelfClosing
                };
                break;
            }

            if (!String.IsNullOrEmpty(CdnIntegrity) && url != null && url == UrlCdn)
            {
                tagBuilder.Attributes["integrity"]   = CdnIntegrity;
                tagBuilder.Attributes["crossorigin"] = "anonymous";
            }
            else if (!String.IsNullOrEmpty(CdnDebugIntegrity) && url != null && url == UrlCdnDebug)
            {
                tagBuilder.Attributes["integrity"]   = CdnDebugIntegrity;
                tagBuilder.Attributes["crossorigin"] = "anonymous";
            }

            if (Attributes != null)
            {
                tagBuilder.MergeAttributes(Attributes);
            }

            if (settings.HasAttributes)
            {
                tagBuilder.MergeAttributes(settings.Attributes);
            }

            if (!String.IsNullOrEmpty(url) && filePathAttributeName != null)
            {
                tagBuilder.MergeAttribute(filePathAttributeName, url, true);
            }
            else if (!String.IsNullOrEmpty(InnerContent))
            {
                tagBuilder.InnerHtml.AppendHtml(InnerContent);
            }

            return(tagBuilder);
        }