mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Merge
--HG-- branch : dev
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
using System.Linq;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.Core.Contents.Extensions;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.Descriptor;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
@@ -59,6 +62,20 @@ namespace Orchard.Specs.Bindings {
|
||||
|
||||
}
|
||||
|
||||
[Given(@"I have a containable content type ""(.*)\""")]
|
||||
public void GivenIHaveAContainableContentType(string name) {
|
||||
var webApp = Binding<WebAppHosting>();
|
||||
webApp.Host.Execute(() => {
|
||||
using (var environment = MvcApplication.CreateStandaloneEnvironment("Default")) {
|
||||
var cdm = environment.Resolve<IContentDefinitionManager>();
|
||||
|
||||
var contentTypeDefinition = new ContentTypeDefinition(name, name);
|
||||
cdm.StoreTypeDefinition(contentTypeDefinition);
|
||||
cdm.AlterTypeDefinition(name, cfg => cfg.WithPart("CommonPart").WithPart("BodyPart").WithPart("RoutePart").WithPart("ContainablePart").Creatable().Draftable());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[Given(@"I have tenant ""(.*)\"" on ""(.*)\"" as ""(.*)\""")]
|
||||
public void GivenIHaveTenantOnSiteAsName(string shellName, string hostName, string siteName) {
|
||||
var webApp = Binding<WebAppHosting>();
|
||||
|
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using Castle.Core.Logging;
|
||||
using HtmlAgilityPack;
|
||||
using log4net.Appender;
|
||||
@@ -190,7 +191,7 @@ namespace Orchard.Specs.Bindings {
|
||||
_doc.Load(new StringReader(Details.ResponseText));
|
||||
}
|
||||
|
||||
[When(@"I follow ""(.*)""")]
|
||||
[When(@"I follow ""([^""]*)""")]
|
||||
public void WhenIFollow(string linkText) {
|
||||
var link = _doc.DocumentNode
|
||||
.SelectNodes("//a")
|
||||
@@ -198,7 +199,24 @@ namespace Orchard.Specs.Bindings {
|
||||
?? _doc.DocumentNode
|
||||
.SelectSingleNode(string.Format("//a[@title='{0}']", linkText));
|
||||
|
||||
var urlPath = link.Attributes["href"].Value;
|
||||
var urlPath = HttpUtility.HtmlDecode(link.Attributes["href"].Value);
|
||||
|
||||
WhenIGoTo(urlPath);
|
||||
}
|
||||
|
||||
[When(@"I follow ""([^""]+)"" where href has ""([^""]+)""")]
|
||||
public void WhenIFollow(string linkText, string hrefFilter) {
|
||||
var link = _doc.DocumentNode
|
||||
.SelectNodes("//a[@href]").Where(elt =>
|
||||
(elt.InnerText == linkText ||
|
||||
(elt.Attributes["title"] != null && elt.Attributes["title"].Value == linkText)) &&
|
||||
elt.Attributes["href"].Value.IndexOf(hrefFilter, StringComparison.OrdinalIgnoreCase) != -1).SingleOrDefault();
|
||||
|
||||
if (link == null) {
|
||||
throw new InvalidOperationException(string.Format("Could not find an anchor with matching text '{0}' and href '{1}'. Document: {2}", linkText, hrefFilter, _doc.DocumentNode.InnerHtml));
|
||||
}
|
||||
var href = link.Attributes["href"].Value;
|
||||
var urlPath = HttpUtility.HtmlDecode(href);
|
||||
|
||||
WhenIGoTo(urlPath);
|
||||
}
|
||||
@@ -269,11 +287,24 @@ namespace Orchard.Specs.Bindings {
|
||||
|
||||
var form = Form.LocateAround(submit);
|
||||
var urlPath = form.Start.GetAttributeValue("action", Details.UrlPath);
|
||||
|
||||
|
||||
var inputs = form.Children
|
||||
.SelectMany(elt => elt.DescendantsAndSelf("input").Concat(elt.Descendants("textarea")))
|
||||
.Where(node => !((node.GetAttributeValue("type", "") == "radio" || node.GetAttributeValue("type", "") == "checkbox") && node.GetAttributeValue("checked", "") != "checked"))
|
||||
.GroupBy(elt => elt.GetAttributeValue("name", elt.GetAttributeValue("id", "")), elt => elt.GetAttributeValue("value", ""))
|
||||
.Where(g => !string.IsNullOrEmpty(g.Key))
|
||||
// add values of <select>s
|
||||
.Concat(
|
||||
// select all <select> elements
|
||||
form.Children.SelectMany(elt => elt.DescendantsAndSelf("select")).Where(elt => elt.Name.Equals("select", StringComparison.OrdinalIgnoreCase))
|
||||
// group them by their name with value that comes from first of:
|
||||
// (1) value of option with 'selected' attribute,
|
||||
// (2) value of first option (none have 'selected'),
|
||||
// (3) empty value (e.g. select with no options)
|
||||
.GroupBy(
|
||||
sel => sel.GetAttributeValue("name", sel.GetAttributeValue("id", "")),
|
||||
sel => (sel.Descendants("option").SingleOrDefault(opt => opt.Attributes["selected"] != null) ?? sel.Descendants("option").FirstOrDefault() ?? new HtmlNode(HtmlNodeType.Element, _doc, 0)).GetAttributeValue("value", "")))
|
||||
.ToDictionary(elt => elt.Key, elt => (IEnumerable<string>)elt);
|
||||
|
||||
if (submit.Attributes.Contains("name"))
|
||||
|
37
src/Orchard.Specs/Lists.feature
Normal file
37
src/Orchard.Specs/Lists.feature
Normal file
@@ -0,0 +1,37 @@
|
||||
Feature: Lists
|
||||
In order to add new lists to my site
|
||||
As an administrator
|
||||
I want to create lists
|
||||
|
||||
Scenario: I can create a new list
|
||||
Given I have installed Orchard
|
||||
When I go to "Admin/Contents/Create/List"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | MyList |
|
||||
And I hit "Save"
|
||||
And I go to "Admin/Contents/List/List"
|
||||
Then I should see "MyList"
|
||||
|
||||
Scenario: I can add content items to a list
|
||||
Given I have installed Orchard
|
||||
And I have a containable content type "MyType"
|
||||
When I go to "Admin/Contents/Create/List"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | MyList |
|
||||
And I hit "Save"
|
||||
And I go to "Admin/Contents/List/List"
|
||||
Then I should see "MyList"
|
||||
When I follow "Contained Items"
|
||||
Then I should see "The 'MyList' List has no content items."
|
||||
When I follow "Create New Content" where href has "ReturnUrl"
|
||||
Then I should see "MyType"
|
||||
When I follow "MyType" where href has "ReturnUrl"
|
||||
And I fill in
|
||||
| name | value |
|
||||
| Routable.Title | MyContentItem |
|
||||
And I hit "Save"
|
||||
And I am redirected
|
||||
Then I should see "Manage Content for MyList"
|
||||
And I should see "MyContentItem"
|
145
src/Orchard.Specs/Lists.feature.cs
generated
Normal file
145
src/Orchard.Specs/Lists.feature.cs
generated
Normal file
@@ -0,0 +1,145 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by SpecFlow (http://www.specflow.org/).
|
||||
// SpecFlow Version:1.4.0.0
|
||||
// Runtime Version:4.0.30319.1
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
// ------------------------------------------------------------------------------
|
||||
#region Designer generated code
|
||||
namespace Orchard.Specs
|
||||
{
|
||||
using TechTalk.SpecFlow;
|
||||
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.4.0.0")]
|
||||
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[NUnit.Framework.TestFixtureAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("Lists")]
|
||||
public partial class ListsFeature
|
||||
{
|
||||
|
||||
private static TechTalk.SpecFlow.ITestRunner testRunner;
|
||||
|
||||
#line 1 "Lists.feature"
|
||||
#line hidden
|
||||
|
||||
[NUnit.Framework.TestFixtureSetUpAttribute()]
|
||||
public virtual void FeatureSetup()
|
||||
{
|
||||
testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner();
|
||||
TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Lists", "In order to add new lists to my site\nAs an administrator\nI want to create lists", GenerationTargetLanguage.CSharp, ((string[])(null)));
|
||||
testRunner.OnFeatureStart(featureInfo);
|
||||
}
|
||||
|
||||
[NUnit.Framework.TestFixtureTearDownAttribute()]
|
||||
public virtual void FeatureTearDown()
|
||||
{
|
||||
testRunner.OnFeatureEnd();
|
||||
testRunner = null;
|
||||
}
|
||||
|
||||
public virtual void ScenarioSetup(TechTalk.SpecFlow.ScenarioInfo scenarioInfo)
|
||||
{
|
||||
testRunner.OnScenarioStart(scenarioInfo);
|
||||
}
|
||||
|
||||
[NUnit.Framework.TearDownAttribute()]
|
||||
public virtual void ScenarioTearDown()
|
||||
{
|
||||
testRunner.OnScenarioEnd();
|
||||
}
|
||||
|
||||
[NUnit.Framework.TestAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("I can create a new list")]
|
||||
public virtual void ICanCreateANewList()
|
||||
{
|
||||
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can create a new list", ((string[])(null)));
|
||||
#line 6
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 7
|
||||
testRunner.Given("I have installed Orchard");
|
||||
#line 8
|
||||
testRunner.When("I go to \"Admin/Contents/Create/List\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table1.AddRow(new string[] {
|
||||
"Routable.Title",
|
||||
"MyList"});
|
||||
#line 9
|
||||
testRunner.And("I fill in", ((string)(null)), table1);
|
||||
#line 12
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 13
|
||||
testRunner.And("I go to \"Admin/Contents/List/List\"");
|
||||
#line 14
|
||||
testRunner.Then("I should see \"MyList\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
}
|
||||
|
||||
[NUnit.Framework.TestAttribute()]
|
||||
[NUnit.Framework.DescriptionAttribute("I can add content items to a list")]
|
||||
public virtual void ICanAddContentItemsToAList()
|
||||
{
|
||||
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can add content items to a list", ((string[])(null)));
|
||||
#line 16
|
||||
this.ScenarioSetup(scenarioInfo);
|
||||
#line 17
|
||||
testRunner.Given("I have installed Orchard");
|
||||
#line 18
|
||||
testRunner.And("I have a containable content type \"MyType\"");
|
||||
#line 19
|
||||
testRunner.When("I go to \"Admin/Contents/Create/List\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table2.AddRow(new string[] {
|
||||
"Routable.Title",
|
||||
"MyList"});
|
||||
#line 20
|
||||
testRunner.And("I fill in", ((string)(null)), table2);
|
||||
#line 23
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 24
|
||||
testRunner.And("I go to \"Admin/Contents/List/List\"");
|
||||
#line 25
|
||||
testRunner.Then("I should see \"MyList\"");
|
||||
#line 26
|
||||
testRunner.When("I follow \"Contained Items\"");
|
||||
#line 27
|
||||
testRunner.Then("I should see \"The \'MyList\' List has no content items.\"");
|
||||
#line 28
|
||||
testRunner.When("I follow \"Create New Content\" where href has \"ReturnUrl\"");
|
||||
#line 29
|
||||
testRunner.Then("I should see \"MyType\"");
|
||||
#line 30
|
||||
testRunner.When("I follow \"MyType\" where href has \"ReturnUrl\"");
|
||||
#line hidden
|
||||
TechTalk.SpecFlow.Table table3 = new TechTalk.SpecFlow.Table(new string[] {
|
||||
"name",
|
||||
"value"});
|
||||
table3.AddRow(new string[] {
|
||||
"Routable.Title",
|
||||
"MyContentItem"});
|
||||
#line 31
|
||||
testRunner.And("I fill in", ((string)(null)), table3);
|
||||
#line 34
|
||||
testRunner.And("I hit \"Save\"");
|
||||
#line 35
|
||||
testRunner.And("I am redirected");
|
||||
#line 36
|
||||
testRunner.Then("I should see \"Manage Content for MyList\"");
|
||||
#line 37
|
||||
testRunner.And("I should see \"MyContentItem\"");
|
||||
#line hidden
|
||||
testRunner.CollectScenarioErrors();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
@@ -161,6 +161,11 @@
|
||||
<Compile Include="Hosting\RequestExtensions.cs" />
|
||||
<Compile Include="Hosting\RequestDetails.cs" />
|
||||
<Compile Include="Hosting\Simple.Web\Global.asax.cs" />
|
||||
<Compile Include="Lists.feature.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Lists.feature</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Media.feature.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
@@ -260,6 +265,10 @@
|
||||
<Generator>SpecFlowSingleFileGenerator</Generator>
|
||||
<LastGenOutput>ContentTypes.feature.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="Lists.feature">
|
||||
<Generator>SpecFlowSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Lists.feature.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="PermissionModel.feature">
|
||||
<Generator>SpecFlowSingleFileGenerator</Generator>
|
||||
<LastGenOutput>PermissionModel.feature.cs</LastGenOutput>
|
||||
|
@@ -77,7 +77,7 @@ namespace Orchard.Core.Settings.Drivers {
|
||||
|
||||
// ensure the base url is absolute if provided
|
||||
if (!String.IsNullOrWhiteSpace(model.Site.BaseUrl)) {
|
||||
if (!model.Site.BaseUrl.ToLower().StartsWith("http")) {
|
||||
if (!Uri.IsWellFormedUriString(model.Site.BaseUrl, UriKind.Absolute)) {
|
||||
updater.AddModelError("BaseUrl", T("The base url must be absolute."));
|
||||
}
|
||||
// if the base url has been modified, try to ping it
|
||||
|
@@ -1,7 +1,4 @@
|
||||
.section-settings {
|
||||
padding:12px 0;
|
||||
}
|
||||
.navicon-settings {
|
||||
.navicon-settings {
|
||||
background-image:url(images/menu.settings.png) !important;
|
||||
}
|
||||
.navicon-settings:hover {
|
||||
|
@@ -61,7 +61,6 @@ namespace Orchard.Web {
|
||||
var localCopy = HostingEnvironment.MapPath(virtualFileCopy);
|
||||
|
||||
if (File.Exists(localCopy)) {
|
||||
|
||||
// result should not be cached, even on proxies
|
||||
Context.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
|
||||
Context.Response.Cache.SetValidUntilExpires(false);
|
||||
@@ -69,12 +68,10 @@ namespace Orchard.Web {
|
||||
Context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
|
||||
Context.Response.Cache.SetNoStore();
|
||||
|
||||
Context.Response.ContentType = "text/html";
|
||||
|
||||
Context.Response.WriteFile(localCopy);
|
||||
Context.Response.End();
|
||||
}
|
||||
else {
|
||||
else if(!File.Exists(Request.PhysicalPath)) {
|
||||
// there is no local copy and the host is not running
|
||||
// wait for the host to initialize
|
||||
_waitHandle.WaitOne();
|
||||
|
@@ -90,7 +90,7 @@ namespace Orchard.Comments.Drivers {
|
||||
var commentedOnContainer = _contentManager.Get(part.Record.CommentedOnContainer);
|
||||
if (commentedOnContainer != null) {
|
||||
var commentedOnContainerIdentity = _contentManager.GetItemMetadata(commentedOnContainer).Identity;
|
||||
context.Element(part.PartDefinition.Name).SetAttributeValue("commentedOnContainer", commentedOnContainerIdentity.ToString());
|
||||
context.Element(part.PartDefinition.Name).SetAttributeValue("CommentedOnContainer", commentedOnContainerIdentity.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -26,7 +26,7 @@
|
||||
@Display.Parts_Container_Manage(ContainerDisplayName: Model.ContainerDisplayName, ContainerContentType: Model.ContainerContentType, ContainerId: containerId)
|
||||
@if (containerId.HasValue) {
|
||||
<div class="manage">
|
||||
@Html.ActionLink(createLinkText, "Create", new { Area = "Contents", Id = (string)Model.Options.SelectedFilter, ContainerId = (int)containerId, ReturnUrl = Html.ViewContext.HttpContext.Request.RawUrl }, new { @class = "button primaryAction" })
|
||||
@Html.ActionLink(createLinkText, "Create", new { Area = "Contents", Id = (string)Model.Options.SelectedFilter, ContainerId = (int)containerId, ReturnUrl = Url.Action("List", "Admin", new { Area = "Orchard.Lists", ContainerId = (int)containerId }) }, new { @class = "button primaryAction" })
|
||||
</div>
|
||||
}
|
||||
@using (Html.BeginFormAntiForgeryPost()) {
|
||||
|
@@ -76,6 +76,6 @@ if (!Model.DatabaseIsPreconfigured) {
|
||||
</div>
|
||||
|
||||
<fieldset>
|
||||
<button class="primaryAction" type="submit">@T("Finish Setup")</button>
|
||||
<button class="primaryAction setupButton" type="submit">@T("Finish Setup")</button>
|
||||
</fieldset>
|
||||
}
|
||||
|
@@ -66,7 +66,7 @@ namespace Orchard.Tags.Drivers {
|
||||
// Merge tags.
|
||||
if (tags.Length > 0) {
|
||||
var currentTags = part.CurrentTags.Select(t => t.TagName);
|
||||
_tagService.UpdateTagsForContentItem(context.ContentItem, tags.Concat(currentTags));
|
||||
_tagService.UpdateTagsForContentItem(context.ContentItem, tags.Concat(currentTags).Distinct());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Core.Contents.Controllers;
|
||||
using Orchard.Environment.Warmup;
|
||||
using Orchard.FileSystems.AppData;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Security;
|
||||
using Orchard.Warmup.Models;
|
||||
@@ -10,9 +18,14 @@ using Orchard.Warmup.Services;
|
||||
namespace Orchard.Warmup.Controllers {
|
||||
public class AdminController : Controller, IUpdateModel {
|
||||
private readonly IWarmupScheduler _warmupScheduler;
|
||||
private readonly IAppDataFolder _appDataFolder;
|
||||
|
||||
public AdminController(IOrchardServices services, IWarmupScheduler warmupScheduler) {
|
||||
public AdminController(
|
||||
IOrchardServices services,
|
||||
IWarmupScheduler warmupScheduler,
|
||||
IAppDataFolder appDataFolder) {
|
||||
_warmupScheduler = warmupScheduler;
|
||||
_appDataFolder = appDataFolder;
|
||||
Services = services;
|
||||
|
||||
T = NullLocalizer.Instance;
|
||||
@@ -63,6 +76,83 @@ namespace Orchard.Warmup.Controllers {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
[FormValueRequired("submit.Extract")]
|
||||
[HttpPost, ActionName("Index")]
|
||||
public ActionResult IndexPostExtract() {
|
||||
var baseUrl = Services.WorkContext.CurrentSite.BaseUrl;
|
||||
baseUrl = VirtualPathUtility.AppendTrailingSlash(baseUrl);
|
||||
|
||||
var part = Services.WorkContext.CurrentSite.As<WarmupSettingsPart>();
|
||||
|
||||
if (String.IsNullOrWhiteSpace(baseUrl) || String.IsNullOrWhiteSpace(part.Urls)) {
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
var regex = new Regex(@"<link\s[^>]*href=""(?<url>[^""]*\.css)""|<script\s[^>]*src=""(?<url>[^""]*\.js)""", RegexOptions.IgnoreCase);
|
||||
var resources = new List<string>();
|
||||
|
||||
// add the already registered urls to remove duplicates
|
||||
using (var urlReader = new StringReader(part.Urls)) {
|
||||
string relativeUrl;
|
||||
while (null != (relativeUrl = urlReader.ReadLine())) {
|
||||
if (String.IsNullOrWhiteSpace(relativeUrl)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
relativeUrl = relativeUrl.Trim();
|
||||
resources.Add(relativeUrl);
|
||||
|
||||
try {
|
||||
var contentUrl = VirtualPathUtility.RemoveTrailingSlash(baseUrl) + relativeUrl;
|
||||
var filename = WarmupUtility.EncodeUrl(contentUrl.TrimEnd('/'));
|
||||
var path = _appDataFolder.Combine("Warmup", filename);
|
||||
|
||||
if(!_appDataFolder.FileExists(path)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var content = _appDataFolder.ReadFile(path);
|
||||
|
||||
// process only html files
|
||||
if (!content.Contains("<html") && !content.Contains("</html")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var localPrefix = Request.ApplicationPath ?? "/";
|
||||
|
||||
var matches = regex.Matches(content);
|
||||
foreach (Match m in matches) {
|
||||
var url = m.Groups["url"].Value;
|
||||
|
||||
if (url.StartsWith(localPrefix, StringComparison.OrdinalIgnoreCase)) {
|
||||
resources.Add(url.Substring(localPrefix.Length));
|
||||
}
|
||||
else if (url.StartsWith(baseUrl, StringComparison.OrdinalIgnoreCase)) {
|
||||
resources.Add("/" + url.Substring(baseUrl.Length));
|
||||
}
|
||||
else if (!url.StartsWith("http://") && !url.StartsWith("/")) {
|
||||
// relative urls e.g., ../, foo.js, ...
|
||||
relativeUrl = VirtualPathUtility.AppendTrailingSlash(relativeUrl);
|
||||
url = VirtualPathUtility.Combine(relativeUrl, url);
|
||||
resources.Add(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
// if something unexpected happens, process next file
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// extract unique urls
|
||||
var uniqueResources = resources.GroupBy(x => x.ToLowerInvariant()).Select(x => x.First()).ToArray();
|
||||
part.Urls = String.Join(System.Environment.NewLine, uniqueResources);
|
||||
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {
|
||||
return TryUpdateModel(model, prefix, includeProperties, excludeProperties);
|
||||
}
|
||||
|
@@ -33,5 +33,6 @@
|
||||
<fieldset>
|
||||
<button class="primaryAction" name="submit" value="@T("Save")" type="submit">@T("Save")</button>
|
||||
<button class="primaryAction" name="submit.Generate" value="@T("Save and generate")" type="submit">@T("Save and generate")</button>
|
||||
<button class="primaryAction" name="submit.Extract" value="@T("Extract resources")" type="submit">@T("Extract resources")</button>
|
||||
</fieldset>
|
||||
}
|
||||
|
@@ -1,17 +1,42 @@
|
||||
/*Yahoo browser reset
|
||||
----------------------------------------------------------*/
|
||||
/* Reset
|
||||
***************************************************************/
|
||||
|
||||
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,
|
||||
blockquote,th,td {margin:0; padding:0; }
|
||||
table { border-collapse:collapse; border-spacing:0; }
|
||||
fieldset,img { border:0; }
|
||||
address,caption,cite,code,dfn,em,strong,th,var { font-style:normal; font-weight:normal; }
|
||||
ol,ul { list-style:none; }
|
||||
caption,th { text-align:left; }
|
||||
h1,h2,h3,h4,h5,h6 { font-size:100%; font-weight:normal; }
|
||||
abbr,acronym { border:0; }
|
||||
q:before,q:after {content:'';}
|
||||
abbr,acronym { border:0;}
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, font, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td, button, submit {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
font-weight: inherit;
|
||||
font-style: inherit;
|
||||
font-size: 100%;
|
||||
font-family: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
/* Remember focus styles! */
|
||||
:focus { outline: 0; }
|
||||
|
||||
body { line-height: 1; color: black; background: white; }
|
||||
ol, ul { list-style: none; }
|
||||
|
||||
/* Tables still need 'cellspacing="0"' in the markup */
|
||||
table { border-collapse: separate; border-spacing: 0; }
|
||||
caption, th, td { text-align: left; font-weight: normal; }
|
||||
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after { content: ""; }
|
||||
blockquote, q { quotes: "" ""; }
|
||||
|
||||
/* HTML 5 elements as block */
|
||||
header, footer, aside, nav, article { display: block; }
|
||||
/* end: reset */
|
||||
|
||||
/*Defaults
|
||||
----------------------------------------------------------*/
|
||||
@@ -81,6 +106,11 @@ form {
|
||||
border:1px solid #DDDEDF;
|
||||
padding:10px 0;
|
||||
background:transparent url(images/backgroundVines.gif) no-repeat right bottom;
|
||||
|
||||
/*----CSS3 properties----*/
|
||||
-webkit-border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
form h2 {
|
||||
@@ -134,20 +164,7 @@ select {
|
||||
width:100%;
|
||||
}
|
||||
|
||||
button.primaryAction, .button.primaryAction, .button.primaryAction:link, .button.primaryAction:visited {
|
||||
background:#4687ad;
|
||||
border:1px solid #405f71;
|
||||
font-size: 102%;
|
||||
font-weight:600;
|
||||
color:#fff;
|
||||
margin:0 0 20px 20px;
|
||||
padding:3px 28px;
|
||||
|
||||
/*CSS3 properties*/
|
||||
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#4687AD', endColorstr='#366581');
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(#4687AD), to(#366581));
|
||||
background:-moz-linear-gradient(top , #4687AD, #366581);
|
||||
}
|
||||
/*----buttons----*/
|
||||
button.remove, .remove.button, .remove.button:link, .remove.button:visited {
|
||||
background-color:#DECCCA;
|
||||
background-image:url(images/tableHeaderBackgroundRed.gif);
|
||||
@@ -167,55 +184,83 @@ button.remove:focus::-moz-focus-inner, .remove.button:focus::-moz-focus-inner {
|
||||
.delete.button {
|
||||
float:right;
|
||||
}
|
||||
input[type="submit"], input[type="reset"], input[type="button"], button, submit, .button, .button:link, .button:visited
|
||||
{
|
||||
color:#333;
|
||||
background:#F5F5F5;
|
||||
border:1px solid #999;
|
||||
cursor:pointer;
|
||||
padding: 0 12px 2px 12px;
|
||||
text-align:center;
|
||||
|
||||
/*CSS3 properties*/
|
||||
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#f5f5f5', endColorstr='#cbcbcb');
|
||||
background: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#cbcbcb));
|
||||
background: -moz-linear-gradient(top, #f5f5f5, #cbcbcb);
|
||||
box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.3);
|
||||
-webkit-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.3);
|
||||
-moz-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.3);
|
||||
border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
}
|
||||
input[type="submit"]:hover,input[type="reset"]:hover, input[type="button"]:hover, button:hover, .button:hover, .button.primaryAction:hover {
|
||||
text-decoration:none;
|
||||
background: #ffac40;
|
||||
.button.disabled, .button.disabled:visited, .button.disabled:hover, .button.disabled:active, .button.disabled:focus {
|
||||
background:#eee;
|
||||
border:1px solid #ababab;
|
||||
color:#ababab;
|
||||
cursor:default;
|
||||
text-shadow: none;
|
||||
box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
}
|
||||
button, .button, a.button {
|
||||
background:#6a7b42;
|
||||
border:1px solid #487328;
|
||||
color:#fff;
|
||||
border:1px solid #bb8b2d;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font: 90% Arial,Helvetica,sans-serif;
|
||||
padding: 4px 14px 2px 14px; /*ie9*/
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
vertical-align: middle;
|
||||
|
||||
/*CSS3 properties*/
|
||||
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#ffac40', endColorstr='#f9760d');
|
||||
background: -webkit-gradient(linear, 0 0, 0 100%, from(#ffac40), to(#f9760d));
|
||||
background: -moz-linear-gradient(top, #ffac40, #f9760d);
|
||||
/*----CSS3 properties----*/
|
||||
text-shadow: rgba(40,53,9,.2) 0px 0px 1px;
|
||||
-webkit-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.2);
|
||||
-moz-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.2);
|
||||
box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.2);
|
||||
|
||||
|
||||
/*----In ie the first couplet sets the alpha value so 00=transparent and ff=opaque)----*/
|
||||
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#ff9bb36c', endColorstr='#ff809f43');
|
||||
background: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(110, 127, 69, 1.0)), rgba((106, 123, 66, 1.0)));
|
||||
background: -moz-linear-gradient(top, rgba(155, 179, 108, 1.0), rgba(128, 159, 67, 1.0));
|
||||
|
||||
|
||||
-webkit-border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
input[type="submit"]:active, input[type="reset"]:active, input[type="button"]:active, button:active, .buton:active, .button.primaryAction:active {
|
||||
button, input.button, x:-moz-any-link {
|
||||
padding: 2px 14px 2px 14px;
|
||||
}
|
||||
button:hover, .button:hover, a.button:hover {
|
||||
border-color:#3a822e;
|
||||
color:#eefcec;
|
||||
text-decoration:none;
|
||||
background: #62a9e2;
|
||||
color:#fff;
|
||||
border:1px solid #bb772d;
|
||||
|
||||
/*CSS3 properties*/
|
||||
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#fece3b', endColorstr='#fe6001');
|
||||
background: -webkit-gradient(linear, 0 0, 0 100%, from(#fece3b), to(#fe6001));
|
||||
background: -moz-linear-gradient(top, #fece3b, #fe6001);
|
||||
box-shadow: inset 0px 0px 1px rgba(254, 225, 109, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.3);
|
||||
-moz-box-shadow: inset 0px 0px 1px rgba(254, 225, 109, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.3);
|
||||
-webkit-box-shadow: inset 1px 1px 1px rgba(254, 225, 109, 0.6), 1px 1px 1px rgba(102, 102, 102, 0.1);
|
||||
background: #809f43;
|
||||
|
||||
/*CSS3 properties*/
|
||||
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#ff6e7f45', endColorstr='#ff6a7b42');
|
||||
background: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(110, 127, 69, 1.0)), rgba((106, 123, 66, 1.0)));
|
||||
background: -moz-linear-gradient(top, rgba(110, 127, 69, 1.0), rgba(106, 123, 66, 1.0));
|
||||
}
|
||||
input[type="submit"]:focus::-moz-focus-inner, button:focus::-moz-focus-inner, .button:focus::-moz-focus-inner {
|
||||
button:active, .buton:active, a.button:active {
|
||||
text-decoration:none;
|
||||
background:#6a7b42;
|
||||
border:1px solid #487328;
|
||||
color:#fff;
|
||||
|
||||
/*CSS3 properties*/
|
||||
text-shadow: rgba(0,0,0,.5) 0px 0px 1px;
|
||||
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#ff9bb36c', endColorstr='#ff809f43');
|
||||
background: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(110, 127, 69, 1.0)), rgba((106, 123, 66, 1.0)));
|
||||
background: -moz-linear-gradient(top, rgba(155, 179, 108, 1.0), rgba(128, 159, 67, 1.0));
|
||||
}
|
||||
button:focus::-moz-focus-inner, .button:focus::-moz-focus-inner {
|
||||
border: 1px dotted transparent;
|
||||
}
|
||||
|
||||
|
||||
.setupButton {
|
||||
margin:0 0 20px 20px;
|
||||
padding:4px 28px;
|
||||
font-size: 105%;
|
||||
font-weight:600;
|
||||
}
|
||||
|
||||
/* Confirmations, Messages and the like
|
||||
***************************************************************/
|
||||
#throbber {
|
||||
|
Reference in New Issue
Block a user