You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by mg...@apache.org on 2014/06/14 14:13:01 UTC

git commit: WICKET-5617 Make it possible to set markup id to CSS header contributions

Repository: wicket
Updated Branches:
  refs/heads/master 281349b08 -> 16e908b54


WICKET-5617 Make it possible to set markup id to CSS header contributions


Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/16e908b5
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/16e908b5
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/16e908b5

Branch: refs/heads/master
Commit: 16e908b54916d3bf9c62a85ba20ee6e7016fe7dc
Parents: 281349b
Author: Martin Tzvetanov Grigorov <mg...@apache.org>
Authored: Sat Jun 14 15:12:39 2014 +0300
Committer: Martin Tzvetanov Grigorov <mg...@apache.org>
Committed: Sat Jun 14 15:12:39 2014 +0300

----------------------------------------------------------------------
 .../wicket/ajax/res/js/wicket-ajax-jquery.js    | 52 ++++++++++---
 .../wicket/core/util/string/CssUtils.java       | 11 ++-
 .../markup/head/CssContentHeaderItem.java       | 11 +--
 .../wicket/markup/head/CssHeaderItem.java       | 24 +++++-
 .../head/JavaScriptContentHeaderItem.java       | 11 +--
 .../markup/head/JavaScriptHeaderItem.java       | 26 +++++++
 .../head/JavaScriptReferenceHeaderItem.java     | 11 +--
 .../head/JavaScriptUrlReferenceHeaderItem.java  | 11 +--
 .../wicket/core/util/string/CssUtilsTest.java   |  4 +-
 wicket-core/src/test/js/head.js                 | 80 ++++++++++++++++++--
 10 files changed, 178 insertions(+), 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/16e908b5/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js b/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js
index a0be252..72509f1 100644
--- a/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js
@@ -2060,10 +2060,16 @@
 				// Process an external stylesheet element
 				processLink: function (context, node) {
 					context.steps.push(function (notify) {
-						// if the element is already in head, skip it
-						if (Wicket.Head.containsElement(node, "href")) {
+						var res = Wicket.Head.containsElement(node, "href");
+						var oldNode = res.oldNode;
+						if (res.contains) {
+							// an element with same href attribute is in document, skip it
 							return FunctionsExecuter.DONE;
+						} else if (oldNode) {
+							// remove another external element with the same id but different href
+							oldNode.parentNode.removeChild(oldNode);
 						}
+
 						// create link element
 						var css = Wicket.Head.createElement("link");
 
@@ -2150,11 +2156,20 @@
 				// Process a script element (both inline and external)
 				processScript: function (context, node) {
 					context.steps.push(function (notify) {
-						// if element with same id is already in document,
-						// or element with same src attribute is in document, skip it
-						if (Wicket.DOM.containsElement(node) ||
-							Wicket.Head.containsElement(node, "src")) {
+
+						if (!node.getAttribute("src") && Wicket.DOM.containsElement(node)) {
+							// if an inline element with same id is already in document, skip it
 							return FunctionsExecuter.DONE;
+						} else {
+							var res = Wicket.Head.containsElement(node, "src");
+							var oldNode = res.oldNode;
+							if (res.contains) {
+								// an element with same src attribute is in document, skip it
+								return FunctionsExecuter.DONE;
+							} else if (oldNode) {
+								// remove another external element with the same id but different src
+								oldNode.parentNode.removeChild(oldNode);
+							}
 						}
 
 						// determine whether it is external javascript (has src attribute set)
@@ -2259,16 +2274,20 @@
 			containsElement: function (element, mandatoryAttribute) {
 				var attr = element.getAttribute(mandatoryAttribute);
 				if (isUndef(attr) || attr === "") {
-					return false;
+					return {
+						contains: false
+					};
 				}
 
+				var elementTagName = element.tagName.toLowerCase();
+				var elementId = element.getAttribute("id");
 				var head = document.getElementsByTagName("head")[0];
 
-				if (element.tagName === "script") {
+				if (elementTagName === "script") {
 					head = document;
 				}
 
-				var nodes = head.getElementsByTagName(element.tagName);
+				var nodes = head.getElementsByTagName(elementTagName);
 
 				for (var i = 0; i < nodes.length; ++i) {
 					var node = nodes[i];
@@ -2276,16 +2295,25 @@
 					// check node names and mandatory attribute values
 					// we also have to check for attribute name that is suffixed by "_".
 					// this is necessary for filtering script references
-					if (node.tagName.toLowerCase() === element.tagName.toLowerCase()) {
+					if (node.tagName.toLowerCase() === elementTagName) {
 
 						var loadedUrl = node.getAttribute(mandatoryAttribute);
 						var loadedUrl_ = node.getAttribute(mandatoryAttribute+"_");
 						if (loadedUrl === attr || loadedUrl_ === attr) {
-							return true;
+							return {
+								contains: true
+							};
+						} else if (elementId && elementId === node.getAttribute("id")) {
+							return {
+								contains: false,
+								oldNode: node
+							};
 						}
 					}
 				}
-				return false;
+				return {
+					contains: false
+				};
 			},
 
 			// Adds a javascript element to page header.

http://git-wip-us.apache.org/repos/asf/wicket/blob/16e908b5/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java b/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
index b065ef5..f5de2c3 100644
--- a/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
+++ b/wicket-core/src/main/java/org/apache/wicket/core/util/string/CssUtils.java
@@ -90,17 +90,24 @@ public final class CssUtils
 	 * @param media
 	 *      the CSS media
 	 */
-	public static void writeLinkUrl(final Response response, final CharSequence url, final CharSequence media)
+	public static void writeLinkUrl(final Response response, final CharSequence url, final CharSequence media,
+	                                final String markupId)
 	{
 		response.write("<link rel=\"stylesheet\" type=\"text/css\" href=\"");
 		response.write(Strings.escapeMarkup(url));
 		response.write("\"");
-		if (media != null)
+		if (Strings.isEmpty(media) == false)
 		{
 			response.write(" media=\"");
 			response.write(Strings.escapeMarkup(media));
 			response.write("\"");
 		}
+		if (Strings.isEmpty(markupId) == false)
+		{
+			response.write(" id=\"");
+			response.write(Strings.escapeMarkup(markupId));
+			response.write("\"");
+		}
 		response.write(" />");
 	}
 

http://git-wip-us.apache.org/repos/asf/wicket/blob/16e908b5/wicket-core/src/main/java/org/apache/wicket/markup/head/CssContentHeaderItem.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/head/CssContentHeaderItem.java b/wicket-core/src/main/java/org/apache/wicket/markup/head/CssContentHeaderItem.java
index ade12b2..80c3609 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/head/CssContentHeaderItem.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/head/CssContentHeaderItem.java
@@ -31,7 +31,6 @@ import org.apache.wicket.util.string.Strings;
 public class CssContentHeaderItem extends CssHeaderItem
 {
 	private final CharSequence css;
-	private final String id;
 
 	/**
 	 * Creates a new {@code CSSContentHeaderItem}.
@@ -46,7 +45,7 @@ public class CssContentHeaderItem extends CssHeaderItem
 	{
 		super(condition);
 		this.css = css;
-		this.id = id;
+		setId(id);
 	}
 
 	/**
@@ -57,14 +56,6 @@ public class CssContentHeaderItem extends CssHeaderItem
 		return css;
 	}
 
-	/**
-	 * @return unique id for the &lt;style&gt; element.
-	 */
-	public String getId()
-	{
-		return id;
-	}
-
 	@Override
 	public void render(Response response)
 	{

http://git-wip-us.apache.org/repos/asf/wicket/blob/16e908b5/wicket-core/src/main/java/org/apache/wicket/markup/head/CssHeaderItem.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/head/CssHeaderItem.java b/wicket-core/src/main/java/org/apache/wicket/markup/head/CssHeaderItem.java
index 3af3d88..dab463c 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/head/CssHeaderItem.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/head/CssHeaderItem.java
@@ -55,6 +55,8 @@ public abstract class CssHeaderItem extends HeaderItem
 	 * </pre></code>
 	 */
 	private final String condition;
+
+	private String markupId;
 	
 	protected CssHeaderItem(String condition)
 	{
@@ -62,6 +64,26 @@ public abstract class CssHeaderItem extends HeaderItem
 	}
 
 	/**
+	 * @return an optional markup id for the &lt;link&gt; HTML element that will be rendered
+	 * for this header item
+	 */
+	public String getId()
+	{
+		return markupId;
+	}
+
+	/**
+	 * @param markupId
+	 *          an optional markup id for this header item
+	 * @return {@code this} object, for method chaining
+	 */
+	public CssHeaderItem setId(String markupId)
+	{
+		this.markupId = markupId;
+		return this;
+	}
+
+	/**
 	 * @return the condition to use for Internet Explorer conditional comments. E.g. "IE 7".
 	 */
 	public String getCondition()
@@ -266,7 +288,7 @@ public abstract class CssHeaderItem extends HeaderItem
 			response.write("]>");
 		}
 
-		CssUtils.writeLinkUrl(response, url, media);
+		CssUtils.writeLinkUrl(response, url, media, getId());
 
 		if (hasCondition)
 		{

http://git-wip-us.apache.org/repos/asf/wicket/blob/16e908b5/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptContentHeaderItem.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptContentHeaderItem.java b/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptContentHeaderItem.java
index a2797ac..a514e18 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptContentHeaderItem.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptContentHeaderItem.java
@@ -31,7 +31,6 @@ import org.apache.wicket.util.string.Strings;
 public class JavaScriptContentHeaderItem extends JavaScriptHeaderItem
 {
 	private final CharSequence javaScript;
-	private final String id;
 
 	/**
 	 * Creates a new {@code JavaScriptContentHeaderItem}.
@@ -48,7 +47,7 @@ public class JavaScriptContentHeaderItem extends JavaScriptHeaderItem
 	{
 		super(condition);
 		this.javaScript = javaScript;
-		this.id = id;
+		setId(id);
 	}
 
 	/**
@@ -59,14 +58,6 @@ public class JavaScriptContentHeaderItem extends JavaScriptHeaderItem
 		return javaScript;
 	}
 
-	/**
-	 * @return unique id for the javascript element.
-	 */
-	public String getId()
-	{
-		return id;
-	}
-
 	@Override
 	public void render(Response response)
 	{

http://git-wip-us.apache.org/repos/asf/wicket/blob/16e908b5/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptHeaderItem.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptHeaderItem.java b/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptHeaderItem.java
index 8109d24..ffb09a2 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptHeaderItem.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptHeaderItem.java
@@ -39,12 +39,38 @@ public abstract class JavaScriptHeaderItem extends HeaderItem
 	 */
 	private final String condition;
 
+	/**
+	 * An optional markup id to set on the rendered &lt;script&gt; HTML element for
+	 * this header item
+	 */
+	private String markupId;
+
 	protected JavaScriptHeaderItem(String condition)
 	{
 		this.condition = condition;
 	}
 
 	/**
+	 * @return unique id for the javascript element.
+	 */
+	public String getId()
+	{
+		return markupId;
+	}
+
+	/**
+	 * Sets the markup id for this header item
+	 * @param markupId
+	 *            the markup id
+	 * @return {@code this} object, for method chaining
+	 */
+	public JavaScriptHeaderItem setId(String markupId)
+	{
+		this.markupId = markupId;
+		return this;
+	}
+
+	/**
 	 * @return the condition to use for Internet Explorer conditional comments. E.g. "IE 7".
 	 */
 	public String getCondition()

http://git-wip-us.apache.org/repos/asf/wicket/blob/16e908b5/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptReferenceHeaderItem.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptReferenceHeaderItem.java b/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptReferenceHeaderItem.java
index d98029f..68df8ba 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptReferenceHeaderItem.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptReferenceHeaderItem.java
@@ -40,7 +40,6 @@ public class JavaScriptReferenceHeaderItem extends JavaScriptHeaderItem
 		IReferenceHeaderItem
 {
 	private final ResourceReference reference;
-	private final String id;
 	private final PageParameters pageParameters;
 	private final boolean defer;
 	private final String charset;
@@ -69,9 +68,9 @@ public class JavaScriptReferenceHeaderItem extends JavaScriptHeaderItem
 		super(condition);
 		this.reference = Args.notNull(reference, "reference");
 		this.pageParameters = pageParameters;
-		this.id = id;
 		this.defer = defer;
 		this.charset = charset;
+		setId(id);
 	}
 
 	/**
@@ -84,14 +83,6 @@ public class JavaScriptReferenceHeaderItem extends JavaScriptHeaderItem
 	}
 
 	/**
-	 * @return the id that will be used to filter duplicate reference
-	 */
-	public String getId()
-	{
-		return id;
-	}
-
-	/**
 	 * @return the parameters for this Javascript resource reference
 	 */
 	public PageParameters getPageParameters()

http://git-wip-us.apache.org/repos/asf/wicket/blob/16e908b5/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptUrlReferenceHeaderItem.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptUrlReferenceHeaderItem.java b/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptUrlReferenceHeaderItem.java
index e8801c5..2fec36a 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptUrlReferenceHeaderItem.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptUrlReferenceHeaderItem.java
@@ -33,7 +33,6 @@ import org.apache.wicket.util.string.Strings;
 public class JavaScriptUrlReferenceHeaderItem extends JavaScriptHeaderItem
 {
 	private final String url;
-	private final String id;
 	private final boolean defer;
 	private final String charset;
 
@@ -58,9 +57,9 @@ public class JavaScriptUrlReferenceHeaderItem extends JavaScriptHeaderItem
 	{
 		super(condition);
 		this.url = url;
-		this.id = id;
 		this.defer = defer;
 		this.charset = charset;
+		setId(id);
 	}
 
 	/**
@@ -72,14 +71,6 @@ public class JavaScriptUrlReferenceHeaderItem extends JavaScriptHeaderItem
 	}
 
 	/**
-	 * @return id that will be used to filter duplicate reference
-	 */
-	public String getId()
-	{
-		return id;
-	}
-
-	/**
 	 * @return if the execution of a script should be deferred (delayed) until after the page has
 	 *         been loaded.
 	 */

http://git-wip-us.apache.org/repos/asf/wicket/blob/16e908b5/wicket-core/src/test/java/org/apache/wicket/core/util/string/CssUtilsTest.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/core/util/string/CssUtilsTest.java b/wicket-core/src/test/java/org/apache/wicket/core/util/string/CssUtilsTest.java
index 3111f11..696953b 100644
--- a/wicket-core/src/test/java/org/apache/wicket/core/util/string/CssUtilsTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/core/util/string/CssUtilsTest.java
@@ -36,8 +36,8 @@ public class CssUtilsTest extends Assert
 		StringResponse response = new StringResponse();
 		String url = "some/url;jsessionid=1234?with=parameters&p1=v1";
 		String media = "some&bad&media";
-		CssUtils.writeLinkUrl(response, url, media);
+		CssUtils.writeLinkUrl(response, url, media, "markupId");
 
-		assertEquals("<link rel=\"stylesheet\" type=\"text/css\" href=\"some/url;jsessionid=1234?with=parameters&amp;p1=v1\" media=\"some&amp;bad&amp;media\" />", response.toString());
+		assertEquals("<link rel=\"stylesheet\" type=\"text/css\" href=\"some/url;jsessionid=1234?with=parameters&amp;p1=v1\" media=\"some&amp;bad&amp;media\" id=\"markupId\" />", response.toString());
 	}
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/16e908b5/wicket-core/src/test/js/head.js
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/js/head.js b/wicket-core/src/test/js/head.js
index 1cfe303..35c178c 100644
--- a/wicket-core/src/test/js/head.js
+++ b/wicket-core/src/test/js/head.js
@@ -84,13 +84,13 @@ jQuery(document).ready(function() {
 
 	test('Wicket.Head.containsElement - unknown attribute', function() {
 		var scriptElement = Wicket.Head.createElement('script');
-		equal(false, Wicket.Head.containsElement(scriptElement, 'unknown'), 'There shouldn\'t be an element with such attribute name');
+		equal(false, Wicket.Head.containsElement(scriptElement, 'unknown').contains, 'There shouldn\'t be an element with such attribute name');
 	});
 
 	test('Wicket.Head.containsElement - check existence of wicket-ajax-debug.js with "src"', function() {
 		var scriptElement = Wicket.Head.createElement('script');
 		scriptElement.src = "../../main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery-debug.js";
-		ok(Wicket.Head.containsElement(scriptElement, 'src'), 'There should be an element for wicket-ajax-debug.js');
+		ok(Wicket.Head.containsElement(scriptElement, 'src').contains, 'There should be an element for wicket-ajax-debug.js');
 	});
 
 	test('Wicket.Head.containsElement - check existence of data/test.js with "src_"', function() {
@@ -104,7 +104,7 @@ jQuery(document).ready(function() {
 
 		script.src = script.src_;
 		// check for existence by 'src' attribute
-		ok(Wicket.Head.containsElement(script, 'src'), 'There should be an element for wicket-ajax-debug.js');
+		ok(Wicket.Head.containsElement(script, 'src').contains, 'There should be an element for wicket-ajax-debug.js');
 	});
 
 	test('Wicket.Head.containsElement - check existence of data/test.js with jsessionid in the url', function() {
@@ -121,10 +121,78 @@ jQuery(document).ready(function() {
 		// add just jsessionid=1
 		Wicket.Head.addElement(script1);
 
-		equal(true, Wicket.Head.containsElement(script1, 'src'), 'The jsessionid part of the URL must be ignored.');
-		equal(false, Wicket.Head.containsElement(script2, 'src'), 'The jsessionid part of the URL must be ignored.');
+		ok(Wicket.Head.containsElement(script1, 'src').contains, 'The jsessionid part of the URL must be ignored.');
+		equal(false, Wicket.Head.containsElement(script2, 'src').contains, 'The jsessionid part of the URL must be ignored.');
 	});
 
+	test('Wicket.Head.containsElement - check replacement of SCRIPT elements with same id', function() {
+		var
+			script1 = jQuery('<script>', {
+				type: 'text/javascript',
+				src: 'data/one.js',
+				id: 'testId'
+			})[0],
+			script2 = jQuery('<script>', {
+				type: 'text/javascript',
+				src: 'data/two.js',
+				id: 'testId'
+			})[0],
+			context = {
+				steps: []
+			};
+
+		Wicket.Head.addElement(script1);
+		ok(Wicket.Head.containsElement(script1, 'src').contains, 'script1 should be in the DOM.');
+
+		Wicket.Head.Contributor.processScript(context, script2);
+		ok(Wicket.Head.containsElement(script1, 'src').contains, 'script1 should be in the DOM - 2.');
+
+		// poor man's FunctionExecuter
+		jQuery.each(context.steps, function(idx, step) {
+			step(function() {});
+		});
+
+		ok(Wicket.Head.containsElement(script2, 'src').contains, 'script2 should be in the DOM.');
+		equal(Wicket.Head.containsElement(script1, 'src').contains, false,
+				'script1 should have been removed from the DOM because a new element with the same id and' +
+				'different "src" has been added');
+	});
+
+	test('Wicket.Head.containsElement - check replacement of <link> elements with same id', function() {
+		var
+			css1 = jQuery('<link>', {
+				type: 'text/css',
+				href: 'data/one.css',
+				id: 'testId'
+			})[0],
+			css2 = jQuery('<link>', {
+				type: 'text/css',
+				href: 'data/two.css',
+				id: 'testId'
+			})[0],
+			context = {
+				steps: []
+			};
+
+			Wicket.Head.addElement(css1);
+			var containsCss1 = Wicket.Head.containsElement(css1, 'href');
+			ok(containsCss1.contains, 'css1 should be in the DOM.');
+
+			Wicket.Head.Contributor.processLink(context, css2);
+			var containsCss2 = Wicket.Head.containsElement(css1, 'href');
+			ok(containsCss2.contains, 'css1 should be still in the DOM');
+
+			// poor man's FunctionExecuter
+			jQuery.each(context.steps, function(idx, step) {
+				step(function() {});
+			});
+
+			ok(Wicket.Head.containsElement(css2, 'href').contains, 'css2 should be in the DOM.');
+			var containsCss3 = Wicket.Head.containsElement(css1, 'href');
+			equal(containsCss3.contains, false,
+					'css1 should have been removed from the DOM because a new element with the same id and' +
+					'different "href" has been added');
+		});
 	module('addJavascript');
 	
 	test('Wicket.Head.addJavascript - add script with text content', function() {
@@ -139,7 +207,7 @@ jQuery(document).ready(function() {
 			src: url
 		}),
 		script = $script[0];
-		ok(Wicket.Head.containsElement(script, 'src'));
+		ok(Wicket.Head.containsElement(script, 'src').contains);
 	});
 
 	module('addJavascripts');