Skip to content

Commit

Permalink
Merge pull request #739 from riganti/fix/location-fallback-page-rewrite
Browse files Browse the repository at this point in the history
Fix LocationFallback overwriting the entire page on postback
  • Loading branch information
cafour authored Sep 6, 2019
2 parents d27bbd5 + 9add047 commit 9759711
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 48 deletions.
14 changes: 13 additions & 1 deletion src/DotVVM.Framework/ResourceManagement/LinkResourceBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,19 @@ public override void Render(IHtmlWriter writer, IDotvvmRequestContext context, s
{
writer.AddAttribute("type", "text/javascript");
writer.RenderBeginTag("script");
writer.WriteUnencodedText($"{LocationFallback.JavascriptCondition} || document.write({JsonConvert.ToString(link, '\'').Replace("<", "\\u003c")})");
var script = JsonConvert.ToString(link, '\'').Replace("<", "\\u003c");
writer.WriteUnencodedText(
$@"if (!({LocationFallback.JavascriptCondition})) {{
var wrapper = document.createElement('div');
wrapper.innerHTML = {script};
var originalScript = wrapper.children[0];
var script = document.createElement('script');
script.src = originalScript.src;
script.type = originalScript.type;
script.text = originalScript.text;
script.id = originalScript.id;
document.head.appendChild(script);
}}");
writer.RenderEndTag();
}
}
Expand Down
46 changes: 24 additions & 22 deletions src/DotVVM.Framework/Resources/Scripts/DotVVM.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 24 additions & 22 deletions src/DotVVM.Framework/Resources/Scripts/DotVVM.ts
Original file line number Diff line number Diff line change
Expand Up @@ -712,46 +712,48 @@ class DotVVM {
callback();
return;
}
var el = <any>elements[offset];
var element = elements[offset];
var waitForScriptLoaded = false;
if (el.tagName.toLowerCase() == "script") {
// create the script element
if (element.tagName.toLowerCase() == "script") {
var originalScript = <HTMLScriptElement>element;
var script = <HTMLScriptElement>document.createElement("script");
if (el.src) {
script.src = el.src;
if (originalScript.src) {
script.src = originalScript.src;
waitForScriptLoaded = true;
}
if (el.type) {
script.type = el.type;
if (originalScript.type) {
script.type = originalScript.type;
}
if (el.text) {
script.text = el.text;
if (originalScript.text) {
script.text = originalScript.text;
}
if (el.id) {
script.id = el.id;
if (element.id) {
script.id = element.id;
}
el = script;
element = script;
}
else if (el.tagName.toLowerCase() == "link") {
else if (element.tagName.toLowerCase() == "link") {
// create link
var originalLink = <HTMLLinkElement>element;
var link = <HTMLLinkElement>document.createElement("link");
if (el.href) {
link.href = el.href;
if (originalLink.href) {
link.href = originalLink.href;
}
if (el.rel) {
link.rel = el.rel;
if (originalLink.rel) {
link.rel = originalLink.rel;
}
if (el.type) {
link.type = el.type;
if (originalLink.type) {
link.type = originalLink.type;
}
el = link;
element = link;
}

// load next script when this is finished
if (waitForScriptLoaded) {
el.onload = () => this.loadResourceElements(elements, offset + 1, callback);
element.addEventListener("load", () => this.loadResourceElements(elements, offset + 1, callback));
element.addEventListener("error", () => this.loadResourceElements(elements, offset + 1, callback));
}
document.head.appendChild(el);
document.head.appendChild(element);
if (!waitForScriptLoaded) {
this.loadResourceElements(elements, offset + 1, callback);
}
Expand Down
7 changes: 6 additions & 1 deletion src/DotVVM.Samples.Common/CommonConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ private static void RegisterResources(DotvvmResourceRepository resources)
resources.Register("ControlSamples_SpaContentPlaceHolder_MasterPageResource", new ScriptResource(new FileResourceLocation("Scripts/testResource2.js")));

resources.Register("FeatureSamples_Resources_CdnUnavailableResourceLoad", new ScriptResource() {
Location = new UrlResourceLocation("http://unavailable.local/testResource.js"),
Location = new UrlResourceLocation("~/nonexistentResource.js"),
LocationFallback = new ResourceLocationFallback("window.dotvvmTestResource", new FileResourceLocation("~/Scripts/testResource.js"))
});

Expand All @@ -52,6 +52,11 @@ private static void RegisterResources(DotvvmResourceRepository resources)
LocationFallback = new ResourceLocationFallback("window.dotvvmTestResource", new FileResourceLocation("~/Scripts/testResource2.js"))
});

resources.Register("FeatureSamples_Resources_RequiredOnPostback", new ScriptResource() {
Location = new UrlResourceLocation("~/nonexistentResource.js"),
LocationFallback = new ResourceLocationFallback("window.dotvvmTestResource", new FileResourceLocation("~/Scripts/testResource.js"))
});

resources.Register("Errors_InvalidLocationFallback", new ScriptResource {
Location = new FileResourceLocation("~/Scripts/testResource.js"),
LocationFallback = new ResourceLocationFallback("window.dotvvmTestResource", new FileResourceLocation("~/Scripts/testResource2.js"))
Expand Down
32 changes: 32 additions & 0 deletions src/DotVVM.Samples.Common/Controls/ResourceRequiringButton.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DotVVM.Framework.Binding;
using DotVVM.Framework.Controls;
using DotVVM.Framework.Hosting;

namespace DotVVM.Samples.BasicSamples.Controls
{
public class ResourceRequiringButton : Button
{
public string ResourceName
{
get { return (string)GetValue(ResourceNameProperty); }
set { SetValue(ResourceNameProperty, value); }
}
public static readonly DotvvmProperty ResourceNameProperty
= DotvvmProperty.Register<string, ResourceRequiringButton>(c => c.ResourceName, null);


protected override void OnPreRender(IDotvvmRequestContext context)
{
if (context.IsPostBack)
{
context.ResourceManager.AddRequiredResource(ResourceName);
}
base.OnPreRender(context);
}
}
}
1 change: 1 addition & 0 deletions src/DotVVM.Samples.Common/DotVVM.Samples.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
<None Remove="Views\FeatureSamples\PostBack\RecursiveTextRepeater2.dotcontrol" />
<None Remove="Views\FeatureSamples\PostBack\UniqueIdGenerationOnPostbackUpdate.dothtml" />
<None Remove="Views\FeatureSamples\Resources\LocationFallback.dothtml" />
<None Remove="Views\FeatureSamples\Resources\RequiredOnPostback.dothtml" />
<None Remove="Views\FeatureSamples\StaticCommand\StaticCommand_NullAssignment.dothtml" />
<None Remove="Views\FeatureSamples\StaticCommand\StaticCommand_TaskSequence.dothtml" />
<None Remove="Views\FeatureSamples\Validation\EnforceClientSideValidationDisabled.dothtml" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
@viewModel object

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Resource required on postback</title>
</head>
<body>
<h1 data-ui="welcome">Welcome</h1>
<cc:ResourceRequiringButton Text="Click on me!"
ResourceName="FeatureSamples_Resources_RequiredOnPostback"
Click="{command: 0}"
data-ui="button"/>
</body>
</html>
20 changes: 19 additions & 1 deletion src/DotVVM.Samples.Tests/Feature/ResourcesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public void Feature_Resources_OnlineNonameResourceLoad()
RunInAllBrowsers(browser => {
browser.NavigateToUrl(SamplesRouteUrls.FeatureSamples_Resources_OnlineNonameResourceLoad);

//click buton
//click button
browser.First("input[type=button]").Click();

//check that alert showed
Expand All @@ -51,6 +51,24 @@ public void Feature_Resources_OnlineNonameResourceLoad()
});
}

[Fact]
public void Feature_Resource_RequiredOnPostback()
{
RunInAllBrowsers(browser => {
browser.NavigateToUrl(SamplesRouteUrls.FeatureSamples_Resources_RequiredOnPostback);
browser.WaitUntilDotvvmInited();

var welcome = browser.Single("welcome", SelectByDataUi);
AssertUI.TextEquals(welcome, "Welcome");

browser.Single("button", SelectByDataUi).Click();
browser.WaitFor(() => AssertUI.AlertTextEquals(browser, "javascript resource loaded!"), 5000);

browser.ConfirmAlert();
browser.WaitFor(() => AssertUI.TextEquals(welcome, "Welcome"), 1000);
});
}

public ResourcesTests(ITestOutputHelper output) : base(output)
{
}
Expand Down
3 changes: 2 additions & 1 deletion src/DotVVM.Testing.Abstractions/SamplesRouteUrls.designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 9759711

Please sign in to comment.