Repository: wicket Updated Branches: refs/heads/master 3cc3fe95c -> 876064cae
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. (cherry picked from commit b82e1cab704e5a7a32df580bae48421deea69fac) Conflicts: wicket-core/src/test/java/org/apache/wicket/ajax/form/AjaxFormSubmitTestPage_expected.html wicket-core/src/test/java/org/apache/wicket/markup/html/form/CheckBoxMultipleChoiceTest.java wicket-core/src/test/java/org/apache/wicket/markup/html/form/RadioChoiceTest.java Project: http://git-wip-us.apache.org/repos/asf/wicket/repo Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/876064ca Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/876064ca Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/876064ca Branch: refs/heads/master Commit: 876064cae6c2d4ebc8a35f3f96333ee438179074 Parents: 3cc3fe9 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:32:02 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/876064ca/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 5a5bd63..dbede58 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/876064ca/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/876064ca/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 73a9b06..03c3f13 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({"u":"./org.apache.wicket.ajax.form.AjaxFormSubmitTestPage?0-1.IBehaviorListener.0-form-submit","m":"POST","c":"submit2","f":"form1","sc":":submit","e":"click","pd":true});; +Wicket.Ajax.ajax({"u":"./org.apache.wicket.ajax.form.AjaxFormSubmitTestPage?0-1.IBehaviorListener.0-form-submit","m":"POST","c":"submit2","f":"form1","sc":"p::submit","e":"click","pd":true});; ;}); /*]]>*/ </script> @@ -24,7 +24,7 @@ Wicket.Ajax.ajax({"u":"./org.apache.wicket.ajax.form.AjaxFormSubmitTestPage?0-1. <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/876064ca/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 8ed5677..e2d9cad 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></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></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\"/></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\"/></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></span>"); + tester.assertResultPage("<span wicket:id=\"testid\"><label>1 <input name=\"testid\" type=\"checkbox\" value=\"0\" id=\"testid1-testid_0\"/></label></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></span>"); + tester.assertResultPage("<span wicket:id=\"testid\"><label><input name=\"testid\" type=\"checkbox\" value=\"0\" id=\"testid1-testid_0\"/> 1</label></span>"); } } http://git-wip-us.apache.org/repos/asf/wicket/blob/876064ca/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 22d040f..ed5151f 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></span>"); + tester.assertResultPage("<span wicket:id=\"testid\"><input name=\"testid\" type=\"radio\" value=\"0\" id=\"testid1-0\"/><label for=\"testid1-0\">1</label></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\"/></span>"); + tester.assertResultPage("<span wicket:id=\"testid\"><label for=\"testid1-0\">1</label><input name=\"testid\" type=\"radio\" value=\"0\" id=\"testid1-0\"/></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></span>"); + tester.assertResultPage("<span wicket:id=\"testid\"><label>1 <input name=\"testid\" type=\"radio\" value=\"0\" id=\"testid1-0\"/></label></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></span>"); + tester.assertResultPage("<span wicket:id=\"testid\"><label><input name=\"testid\" type=\"radio\" value=\"0\" id=\"testid1-0\"/> 1</label></span>"); } }