Repository: wicket Updated Branches: refs/heads/wicket-6.x a4ae23c63 -> b82e1cab7
Avoid using input names that conflict with any DOM API names. Using input names that conflict with DOM API method and attribute names interferes with JavaScript ability to use DOM API on the form element. Project: http://git-wip-us.apache.org/repos/asf/wicket/repo Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/b82e1cab Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/b82e1cab Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/b82e1cab Branch: refs/heads/wicket-6.x Commit: b82e1cab704e5a7a32df580bae48421deea69fac Parents: a4ae23c Author: Jesse Long <jl...@apache.org> Authored: Thu Oct 16 16:04:57 2014 +0200 Committer: Jesse Long <jl...@apache.org> Committed: Thu Oct 16 16:04:57 2014 +0200 ---------------------------------------------------------------------- .../apache/wicket/markup/html/form/Form.java | 13 +- .../html/form/JavaScriptReservedNames.java | 151 +++++++++++++++++++ .../form/AjaxFormSubmitTestPage_expected.html | 4 +- .../html/form/CheckBoxMultipleChoiceTest.java | 16 +- .../markup/html/form/RadioChoiceTest.java | 16 +- 5 files changed, 178 insertions(+), 22 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/wicket/blob/b82e1cab/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java index 1292896..b4c7d64 100644 --- a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java +++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Form.java @@ -2107,13 +2107,18 @@ public class Form<T> extends WebMarkupContainer implements IFormSubmitListener, } /* - * having input name "submit" causes problems with JavaScript, so we create a unique string - * to replace it by prepending a path separator, as this identification can be assigned to - * an submit form component name + * Certain input names causes problems with JavaScript. If the input name would cause a + * problem, we create a replacement unique name by prefixing the name with a path that + * would otherwise never be used (blank id in path). + * + * Input names must start with [A-Za-z] according to HTML 4.01 spec. HTML 5 allows almost + * anything. */ - if ("submit".equals(inputName.toString())) + if (JavaScriptReservedNames.isNameReserved(inputName.toString())) { inputName.prepend(Component.PATH_SEPARATOR); + inputName.prepend(Component.PATH_SEPARATOR); + inputName.prepend("p"); } return inputName.toString(); } http://git-wip-us.apache.org/repos/asf/wicket/blob/b82e1cab/wicket-core/src/main/java/org/apache/wicket/markup/html/form/JavaScriptReservedNames.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/JavaScriptReservedNames.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/JavaScriptReservedNames.java new file mode 100644 index 0000000..5c9b05e --- /dev/null +++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/JavaScriptReservedNames.java @@ -0,0 +1,151 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.wicket.markup.html.form; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.wicket.util.lang.Args; + +/** + * Utility class for names used by JavaScript DOM API. These names should not be used as form element names, as they would interfere + * with JavaScripts that attempt to use DOM API. + * + * @author Jesse Long + */ +class JavaScriptReservedNames +{ + /** + * Set of names reserved by JavaScript DOM API. + */ + private static final Set<String> RESERVED_NAMES = new HashSet<String>(100); + + static + { + /* + * DOM 3 CORE Node interface + * http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-1950641247 + */ + RESERVED_NAMES.add("nodeName"); + RESERVED_NAMES.add("nodeValue"); + RESERVED_NAMES.add("nodeType"); + RESERVED_NAMES.add("parentNode"); + RESERVED_NAMES.add("childNodes"); + RESERVED_NAMES.add("firstChild"); + RESERVED_NAMES.add("lastChild"); + RESERVED_NAMES.add("previousSibling"); + RESERVED_NAMES.add("nextSibling"); + RESERVED_NAMES.add("attributes"); + RESERVED_NAMES.add("ownerDocument"); + RESERVED_NAMES.add("insertBefore"); + RESERVED_NAMES.add("replaceChild"); + RESERVED_NAMES.add("removeChild"); + RESERVED_NAMES.add("appendChild"); + RESERVED_NAMES.add("hasChildNodes"); + RESERVED_NAMES.add("cloneNode"); + RESERVED_NAMES.add("normalize"); + RESERVED_NAMES.add("isSupported"); + RESERVED_NAMES.add("namespaceURI"); + RESERVED_NAMES.add("prefix"); + RESERVED_NAMES.add("localName"); + RESERVED_NAMES.add("hasAttributes"); + RESERVED_NAMES.add("createDocumentPosition"); + RESERVED_NAMES.add("textContent"); + RESERVED_NAMES.add("isSameNode"); + RESERVED_NAMES.add("lookupPrefix"); + RESERVED_NAMES.add("isDefaultNamespace"); + RESERVED_NAMES.add("lookupNamespaceURI"); + RESERVED_NAMES.add("isEqualNode"); + RESERVED_NAMES.add("getFeature"); + RESERVED_NAMES.add("setUserData"); + RESERVED_NAMES.add("getUserData"); + + /* + * DOM 3 CORE Element interface + * http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-745549614 + */ + RESERVED_NAMES.add("tagName"); + RESERVED_NAMES.add("getAttribute"); + RESERVED_NAMES.add("setAttribute"); + RESERVED_NAMES.add("removeAttribute"); + RESERVED_NAMES.add("getAttributeNode"); + RESERVED_NAMES.add("setAttributeNode"); + RESERVED_NAMES.add("removeAttributeNode"); + RESERVED_NAMES.add("getElementsByTagName"); + RESERVED_NAMES.add("getAttributeNS"); + RESERVED_NAMES.add("setAttributeNS"); + RESERVED_NAMES.add("removeAttributeNS"); + RESERVED_NAMES.add("getAttributeNodeNS"); + RESERVED_NAMES.add("setAttributeNodeNS"); + RESERVED_NAMES.add("getElementsByTagNameNS"); + RESERVED_NAMES.add("hasAttribute"); + RESERVED_NAMES.add("hasAttributeNS"); + RESERVED_NAMES.add("schemaTypeInfo"); + RESERVED_NAMES.add("setIdAttribute"); + RESERVED_NAMES.add("setIdAttributeNS"); + RESERVED_NAMES.add("setIdAttributeNode"); + + /* + * DOM 2 HTML HTMLElement interface + * http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-58190037 + */ + RESERVED_NAMES.add("id"); + RESERVED_NAMES.add("title"); + RESERVED_NAMES.add("lang"); + RESERVED_NAMES.add("dir"); + RESERVED_NAMES.add("className"); + + /* + * DOM 2 HTML HTMLFormElement interface + * http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-40002357 + */ + RESERVED_NAMES.add("elements"); + RESERVED_NAMES.add("length"); + RESERVED_NAMES.add("name"); + RESERVED_NAMES.add("acceptCharset"); + RESERVED_NAMES.add("action"); + RESERVED_NAMES.add("enctype"); + RESERVED_NAMES.add("method"); + RESERVED_NAMES.add("target"); + RESERVED_NAMES.add("submit"); + RESERVED_NAMES.add("reset"); + } + + /** + * Private constructor for utility class. + */ + private JavaScriptReservedNames() + { + } + + /** + * Returns {@code true} if the name is used by the JavaScript DOM API. If the name is used in the JavaScript DOM API, we + * should not name a form element with this name, as it would interfere with a JavaScript's ability to use the DOM API on + * the form element. + * + * @param name + * The name to check. + * + * @return {@code true} if the name is used by the JavaScript DOM API. + */ + public static boolean isNameReserved(String name) + { + Args.notNull(name, "name"); + + return RESERVED_NAMES.contains(name); + } +} http://git-wip-us.apache.org/repos/asf/wicket/blob/b82e1cab/wicket-core/src/test/java/org/apache/wicket/ajax/form/AjaxFormSubmitTestPage_expected.html ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/ajax/form/AjaxFormSubmitTestPage_expected.html b/wicket-core/src/test/java/org/apache/wicket/ajax/form/AjaxFormSubmitTestPage_expected.html index e0c1349..d187a06 100644 --- a/wicket-core/src/test/java/org/apache/wicket/ajax/form/AjaxFormSubmitTestPage_expected.html +++ b/wicket-core/src/test/java/org/apache/wicket/ajax/form/AjaxFormSubmitTestPage_expected.html @@ -16,7 +16,7 @@ Wicket.Ajax.baseUrl="wicket/bookmarkable/org.apache.wicket.ajax.form.AjaxFormSub <script type="text/javascript" > /*<![CDATA[*/ Wicket.Event.add(window, "domready", function(event) { -Wicket.Ajax.ajax({"f":"form1","u":"./org.apache.wicket.ajax.form.AjaxFormSubmitTestPage?0-1.IBehaviorListener.0-form-submit","e":"click","c":"submit2","sc":":submit","m":"POST"});; +Wicket.Ajax.ajax({"f":"form1","u":"./org.apache.wicket.ajax.form.AjaxFormSubmitTestPage?0-1.IBehaviorListener.0-form-submit","e":"click","c":"submit2","sc":"p::submit","m":"POST"});; ;}); /*]]>*/ </script> @@ -24,7 +24,7 @@ Wicket.Ajax.ajax({"f":"form1","u":"./org.apache.wicket.ajax.form.AjaxFormSubmitT <form wicket:id="form" id="form1" method="post" action="./org.apache.wicket.ajax.form.AjaxFormSubmitTestPage?0-1.IFormSubmitListener-form"><div style="width:0px;height:0px;position:absolute;left:-100px;top:-100px;overflow:hidden"><input type="hidden" name="form1_hf_0" id="form1_hf_0" /></div> <input type="text" wicket:id="txt1" value="foo" name="txt1"/> <input type="text" wicket:id="txt2" value="bar" name="txt2"/> - <input type="submit" value="Submit" wicket:id="submit" name=":submit" id="submit2"/> + <input type="submit" value="Submit" wicket:id="submit" name="p::submit" id="submit2"/> </form> </body> </html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/wicket/blob/b82e1cab/wicket-core/src/test/java/org/apache/wicket/markup/html/form/CheckBoxMultipleChoiceTest.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/form/CheckBoxMultipleChoiceTest.java b/wicket-core/src/test/java/org/apache/wicket/markup/html/form/CheckBoxMultipleChoiceTest.java index 219fedd..658af02 100644 --- a/wicket-core/src/test/java/org/apache/wicket/markup/html/form/CheckBoxMultipleChoiceTest.java +++ b/wicket-core/src/test/java/org/apache/wicket/markup/html/form/CheckBoxMultipleChoiceTest.java @@ -149,39 +149,39 @@ public class CheckBoxMultipleChoiceTest extends WicketTestCase @Test public void defaultLabelPositionIsAfter() throws Exception { - CheckBoxMultipleChoice<Integer> radioChoice = new CheckBoxMultipleChoice<Integer>("id", Arrays.asList(1)); + CheckBoxMultipleChoice<Integer> radioChoice = new CheckBoxMultipleChoice<Integer>("testid", Arrays.asList(1)); tester.startComponentInPage(radioChoice); - tester.assertResultPage("<span wicket:id=\"id\"><input name=\"id\" type=\"checkbox\" value=\"0\" id=\"id1-id_0\"/><label for=\"id1-id_0\">1</label><br/>\n</span>"); + tester.assertResultPage("<span wicket:id=\"testid\"><input name=\"testid\" type=\"checkbox\" value=\"0\" id=\"testid1-testid_0\"/><label for=\"testid1-testid_0\">1</label><br/>\n</span>"); } @Test public void labelPositionBefore() throws Exception { - CheckBoxMultipleChoice<Integer> radioChoice = new CheckBoxMultipleChoice<Integer>("id", Arrays.asList(1)); + CheckBoxMultipleChoice<Integer> radioChoice = new CheckBoxMultipleChoice<Integer>("testid", Arrays.asList(1)); radioChoice.setLabelPosition(AbstractChoice.LabelPosition.BEFORE); tester.startComponentInPage(radioChoice); - tester.assertResultPage("<span wicket:id=\"id\"><label for=\"id1-id_0\">1</label><input name=\"id\" type=\"checkbox\" value=\"0\" id=\"id1-id_0\"/><br/>\n</span>"); + tester.assertResultPage("<span wicket:id=\"testid\"><label for=\"testid1-testid_0\">1</label><input name=\"testid\" type=\"checkbox\" value=\"0\" id=\"testid1-testid_0\"/><br/>\n</span>"); } @Test public void labelPositionWrapBefore() throws Exception { - CheckBoxMultipleChoice<Integer> radioChoice = new CheckBoxMultipleChoice<Integer>("id", Arrays.asList(1)); + CheckBoxMultipleChoice<Integer> radioChoice = new CheckBoxMultipleChoice<Integer>("testid", Arrays.asList(1)); radioChoice.setLabelPosition(AbstractChoice.LabelPosition.WRAP_BEFORE); tester.startComponentInPage(radioChoice); - tester.assertResultPage("<span wicket:id=\"id\"><label>1 <input name=\"id\" type=\"checkbox\" value=\"0\" id=\"id1-id_0\"/></label><br/>\n</span>"); + tester.assertResultPage("<span wicket:id=\"testid\"><label>1 <input name=\"testid\" type=\"checkbox\" value=\"0\" id=\"testid1-testid_0\"/></label><br/>\n</span>"); } @Test public void labelPositionWrapAfter() throws Exception { - CheckBoxMultipleChoice<Integer> radioChoice = new CheckBoxMultipleChoice<Integer>("id", Arrays.asList(1)); + CheckBoxMultipleChoice<Integer> radioChoice = new CheckBoxMultipleChoice<Integer>("testid", Arrays.asList(1)); radioChoice.setLabelPosition(AbstractChoice.LabelPosition.WRAP_AFTER); tester.startComponentInPage(radioChoice); - tester.assertResultPage("<span wicket:id=\"id\"><label><input name=\"id\" type=\"checkbox\" value=\"0\" id=\"id1-id_0\"/> 1</label><br/>\n</span>"); + tester.assertResultPage("<span wicket:id=\"testid\"><label><input name=\"testid\" type=\"checkbox\" value=\"0\" id=\"testid1-testid_0\"/> 1</label><br/>\n</span>"); } } http://git-wip-us.apache.org/repos/asf/wicket/blob/b82e1cab/wicket-core/src/test/java/org/apache/wicket/markup/html/form/RadioChoiceTest.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/form/RadioChoiceTest.java b/wicket-core/src/test/java/org/apache/wicket/markup/html/form/RadioChoiceTest.java index 496a389..6dd6c0d 100644 --- a/wicket-core/src/test/java/org/apache/wicket/markup/html/form/RadioChoiceTest.java +++ b/wicket-core/src/test/java/org/apache/wicket/markup/html/form/RadioChoiceTest.java @@ -26,39 +26,39 @@ public class RadioChoiceTest extends WicketTestCase @Test public void defaultLabelPositionIsAfter() throws Exception { - RadioChoice<Integer> radioChoice = new RadioChoice<Integer>("id", Arrays.asList(1)); + RadioChoice<Integer> radioChoice = new RadioChoice<Integer>("testid", Arrays.asList(1)); tester.startComponentInPage(radioChoice); - tester.assertResultPage("<span wicket:id=\"id\"><input name=\"id\" type=\"radio\" value=\"0\" id=\"id1-0\"/><label for=\"id1-0\">1</label><br />\n</span>"); + tester.assertResultPage("<span wicket:id=\"testid\"><input name=\"testid\" type=\"radio\" value=\"0\" id=\"testid1-0\"/><label for=\"testid1-0\">1</label><br />\n</span>"); } @Test public void labelPositionBefore() throws Exception { - RadioChoice<Integer> radioChoice = new RadioChoice<Integer>("id", Arrays.asList(1)); + RadioChoice<Integer> radioChoice = new RadioChoice<Integer>("testid", Arrays.asList(1)); radioChoice.setLabelPosition(AbstractChoice.LabelPosition.BEFORE); tester.startComponentInPage(radioChoice); - tester.assertResultPage("<span wicket:id=\"id\"><label for=\"id1-0\">1</label><input name=\"id\" type=\"radio\" value=\"0\" id=\"id1-0\"/><br />\n</span>"); + tester.assertResultPage("<span wicket:id=\"testid\"><label for=\"testid1-0\">1</label><input name=\"testid\" type=\"radio\" value=\"0\" id=\"testid1-0\"/><br />\n</span>"); } @Test public void labelPositionWrapBefore() throws Exception { - RadioChoice<Integer> radioChoice = new RadioChoice<Integer>("id", Arrays.asList(1)); + RadioChoice<Integer> radioChoice = new RadioChoice<Integer>("testid", Arrays.asList(1)); radioChoice.setLabelPosition(AbstractChoice.LabelPosition.WRAP_BEFORE); tester.startComponentInPage(radioChoice); - tester.assertResultPage("<span wicket:id=\"id\"><label>1 <input name=\"id\" type=\"radio\" value=\"0\" id=\"id1-0\"/></label><br />\n</span>"); + tester.assertResultPage("<span wicket:id=\"testid\"><label>1 <input name=\"testid\" type=\"radio\" value=\"0\" id=\"testid1-0\"/></label><br />\n</span>"); } @Test public void labelPositionWrapAfter() throws Exception { - RadioChoice<Integer> radioChoice = new RadioChoice<Integer>("id", Arrays.asList(1)); + RadioChoice<Integer> radioChoice = new RadioChoice<Integer>("testid", Arrays.asList(1)); radioChoice.setLabelPosition(AbstractChoice.LabelPosition.WRAP_AFTER); tester.startComponentInPage(radioChoice); - tester.assertResultPage("<span wicket:id=\"id\"><label><input name=\"id\" type=\"radio\" value=\"0\" id=\"id1-0\"/> 1</label><br />\n</span>"); + tester.assertResultPage("<span wicket:id=\"testid\"><label><input name=\"testid\" type=\"radio\" value=\"0\" id=\"testid1-0\"/> 1</label><br />\n</span>"); } }