Updated Branches: refs/heads/master fbdf1a70d -> e81c4b2fe
TAP5-1863 Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/e81c4b2f Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/e81c4b2f Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/e81c4b2f Branch: refs/heads/master Commit: e81c4b2fedf16a30f6fdeadf79d59513579d4e20 Parents: fbdf1a7 Author: Thiago H. de Paula Figueiredo <[email protected]> Authored: Sat Feb 8 15:49:19 2014 -0200 Committer: Thiago H. de Paula Figueiredo <[email protected]> Committed: Sat Feb 8 15:49:19 2014 -0200 ---------------------------------------------------------------------- .../META-INF/modules/t5/core/alert.coffee | 15 +++++++--- .../java/org/apache/tapestry5/alerts/Alert.java | 26 +++++++++++++---- .../apache/tapestry5/alerts/AlertManager.java | 17 ++++++++++- .../internal/alerts/AlertManagerImpl.java | 9 ++++-- .../integration/app1/AlertsTests.groovy | 30 +++++++++++++++++++- .../integration/app1/pages/AlertsDemo.java | 7 +++-- 6 files changed, 88 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/e81c4b2f/tapestry-core/src/main/coffeescript/META-INF/modules/t5/core/alert.coffee ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/coffeescript/META-INF/modules/t5/core/alert.coffee b/tapestry-core/src/main/coffeescript/META-INF/modules/t5/core/alert.coffee index 4816b8f..37683d5 100644 --- a/tapestry-core/src/main/coffeescript/META-INF/modules/t5/core/alert.coffee +++ b/tapestry-core/src/main/coffeescript/META-INF/modules/t5/core/alert.coffee @@ -114,14 +114,21 @@ define ["./dom", "./console", "./messages", "./ajax", "underscore", "./bootstrap # Note that `data-dismiss=alert` is purposely excluded # - we want to handle closes w/ notifications to the server if not transient # - we don't want to rely on bootstrap.js, as that will drag jQuery into the application - # Also, the <span> tag makes it easier to pull out just the content when doing tests. + # Also, the <span> tag makes it easier to pull out just the content when doing tests, + # but we only add this add if the alert doesn't have a message that contains markup (TAP5-1863) element = dom.create "div", "data-alert-id": data.id class: "alert alert-dismissable " + className - """ - <button type="button" class="close">×</button> - <span>#{content}</span> + if data.markup """ + <button type="button" class="close">×</button> + #{content} + """ + else + """ + <button type="button" class="close">×</button> + <span>#{content}</span> + """ container.append element http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/e81c4b2f/tapestry-core/src/main/java/org/apache/tapestry5/alerts/Alert.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/alerts/Alert.java b/tapestry-core/src/main/java/org/apache/tapestry5/alerts/Alert.java index b7a8d8d..a4fd5a6 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/alerts/Alert.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/alerts/Alert.java @@ -23,7 +23,8 @@ import java.util.concurrent.atomic.AtomicLong; /** * An Alert that may be presented to the user. The Alert has a message, but also includes * a severity (that controls how it is presented to the user), and a duration (that controls how long - * it is presented to the user). + * it is presented to the user). If the <code>markup</code> field is <code>true</code>, + * the message is treated as HTML and used without any escaping. * * @since 5.3 */ @@ -42,6 +43,12 @@ public class Alert implements Serializable public final Severity severity; public final String message; + + /** + * Defines whether the message will be treated as HTML or not. + * @since 5.4 + */ + public final boolean markup; /** * Alert with default duration of {@link Duration#SINGLE} and default severity @@ -57,11 +64,16 @@ public class Alert implements Serializable */ public Alert(Severity severity, String message) { - this(Duration.SINGLE, severity, message); + this(Duration.SINGLE, severity, message, false); } public Alert(Duration duration, Severity severity, String message) { + this(duration, severity, message, false); + } + + public Alert(Duration duration, Severity severity, String message, boolean markup) + { assert duration != null; assert severity != null; assert InternalUtils.isNonBlank(message); @@ -69,20 +81,22 @@ public class Alert implements Serializable this.duration = duration; this.severity = severity; this.message = message; + this.markup = markup; } public String toString() { - return String.format("Alert[%s %s %s]", + return String.format("Alert[%s %s %s %s]", duration.name(), severity.name(), - message); + message, + markup); } public JSONObject toJSON() { JSONObject result = new JSONObject("message", message, - "severity", severity.name().toLowerCase() ); + "severity", severity.name().toLowerCase(), "markup", markup ); if (duration == Duration.TRANSIENT) { @@ -93,7 +107,7 @@ public class Alert implements Serializable { result.put("id", id); } - + return result; } } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/e81c4b2f/tapestry-core/src/main/java/org/apache/tapestry5/alerts/AlertManager.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/alerts/AlertManager.java b/tapestry-core/src/main/java/org/apache/tapestry5/alerts/AlertManager.java index c63078b..8304804 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/alerts/AlertManager.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/alerts/AlertManager.java @@ -14,6 +14,8 @@ package org.apache.tapestry5.alerts; +import org.apache.tapestry5.ioc.annotations.IncompatibleChange; + /** * Manages {@link Alert}s (using the {@link AlertStorage} SSO. The behavior of the service switches during * an Ajax request to directly add JavaScript to present the alerts. @@ -52,11 +54,24 @@ public interface AlertManager void error(String message); /** - * Adds an alert with configurable severity and duration. + * Adds an alert with configurable severity and duration. Message isn't treated + * as HTML, being HTML-escaped. * * @param duration controls how long the alert is presented to the user * @param severity controls how the alert is presented to the user * @param message to present to the user */ void alert(Duration duration, Severity severity, String message); + + /** + * Adds an alert with configurable severity and duration. + * + * @param duration controls how long the alert is presented to the user + * @param severity controls how the alert is presented to the user + * @param message to present to the user + * @param markup whether to treat the message as raw HTML (true) or escape it (false). + */ + @IncompatibleChange(details = "Added in 5.4 in order to support HTML in alerts", release = "5.4") + void alert(Duration duration, Severity severity, String message, boolean markup); + } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/e81c4b2f/tapestry-core/src/main/java/org/apache/tapestry5/internal/alerts/AlertManagerImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/alerts/AlertManagerImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/alerts/AlertManagerImpl.java index 66a6e95..2bfe6be 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/alerts/AlertManagerImpl.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/alerts/AlertManagerImpl.java @@ -61,10 +61,15 @@ public class AlertManagerImpl implements AlertManager { alert(Duration.SINGLE, Severity.ERROR, message); } - + public void alert(Duration duration, Severity severity, String message) { - final Alert alert = new Alert(duration, severity, message); + alert(duration, severity, message, false); + } + + public void alert(Duration duration, Severity severity, String message, boolean markup) + { + final Alert alert = new Alert(duration, severity, message, markup); if (request.isXHR()) { http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/e81c4b2f/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/AlertsTests.groovy ---------------------------------------------------------------------- diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/AlertsTests.groovy b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/AlertsTests.groovy index e7019e0..ed540cd 100644 --- a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/AlertsTests.groovy +++ b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/AlertsTests.groovy @@ -22,7 +22,7 @@ import org.testng.annotations.Test * @since 5.3 */ class AlertsTests extends App1TestCase { - + def CONTAINER = "[data-container-type=alerts]" @Test @@ -54,6 +54,19 @@ class AlertsTests extends App1TestCase { // Check that the alert container is now empty assertText "css=$CONTAINER", "" + + // Now with markup + openLinks "Alerts Demo", "Reset Alerts Storage" + + select "id=severity", "Warn" + select "id=duration", "Single" + check "id=markup" + type "id=message", "<a><span>Markup!</span></a>" + + clickAndWait "//input[@value='Traditional Update']" + + assert isElementPresent("//div[@class='alert alert-dismissable alert-warning']/a/span[text()='Markup!']") + } @Test @@ -103,6 +116,21 @@ class AlertsTests extends App1TestCase { // Check that the alert container is now empty assertText "css=$CONTAINER", "" + + // Now with markup + openLinks "Alerts Demo", "Reset Alerts Storage" + + select "css=#ajax select[name=\"severity\"]", "Warn" + select "css=#ajax select[name=\"duration\"]", "Single" + check "css=#ajax input[name='markup']" + type "css=#ajax input[name='message']", "<a><span>Markup!</span></a>" + + click "//input[@value='Ajax Update']" + + waitForCSSSelectedElementToAppear "$CONTAINER .alert" + + assert isElementPresent("//div[@class='alert alert-dismissable alert-warning']/a/span[text()='Markup!']") + } /** Disabled by HLS 7-oct-2011; there's a timing issue that makes it very fragile. */ http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/e81c4b2f/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/AlertsDemo.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/AlertsDemo.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/AlertsDemo.java index 7a371ed..ea36d2e 100644 --- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/AlertsDemo.java +++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/AlertsDemo.java @@ -33,6 +33,9 @@ public class AlertsDemo @Validate("required") @Width(80) private String message; + + @Property + private boolean markup; @Persist(PersistenceConstants.FLASH) @Property @@ -50,13 +53,13 @@ public class AlertsDemo void onSuccessFromTraditional() { alertManager.info("Traditional form submission"); - alertManager.alert(duration, severity, message); + alertManager.alert(duration, severity, message, markup); } Object onSuccessFromAjax() { alertManager.info("Ajax form submission"); - alertManager.alert(duration, severity, message); + alertManager.alert(duration, severity, message, markup); if (redirectToIndex) {
