From 58853fe47bb01a0c0c2b5c380056d22ccccd6f08 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Thu, 25 Aug 2016 13:21:36 +0300 Subject: Move old TextField to compatibility package Change-Id: Ic1e8d3f9859f5e496c0e27e2fece4b5a9da74f01 --- .../java/com/vaadin/client/ui/VTextualDate.java | 15 +- .../vaadin/client/v7/ui/VLegacyPasswordField.java | 34 - .../com/vaadin/client/v7/ui/VLegacyTextField.java | 533 -------------- .../v7/ui/textfield/LegacyTextFieldConnector.java | 124 ---- .../com/vaadin/v7/client/ui/VOptionGroupBase.java | 3 +- .../com/vaadin/v7/client/ui/VPasswordField.java | 34 + .../java/com/vaadin/v7/client/ui/VScrollTable.java | 5 +- .../java/com/vaadin/v7/client/ui/VTextArea.java | 3 +- .../java/com/vaadin/v7/client/ui/VTextField.java | 533 ++++++++++++++ .../ui/optiongroup/OptionGroupBaseConnector.java | 4 +- .../ui/passwordfield/PasswordFieldConnector.java | 10 +- .../v7/client/ui/textarea/TextAreaConnector.java | 4 +- .../v7/client/ui/textfield/TextFieldConnector.java | 124 ++++ .../main/java/com/vaadin/v7/event/FieldEvents.java | 109 +++ .../java/com/vaadin/v7/ui/AbstractTextField.java | 813 ++++++++++++++++++++ .../src/main/java/com/vaadin/v7/ui/TextField.java | 151 ++++ .../tests/server/PropertysetItemListenersTest.java | 14 - .../converter/AnyEnumToStringConverterTest.java | 129 ++++ .../tests/data/converter/ConverterFactoryTest.java | 128 ++++ .../data/converter/DateToLongConverterTest.java | 28 + .../data/converter/DateToSqlDateConverterTest.java | 28 + .../converter/DefaultConverterFactoryTest.java | 124 ++++ .../SpecificEnumToStringConverterTest.java | 125 ++++ .../converter/StringToBigDecimalConverterTest.java | 59 ++ .../converter/StringToBigIntegerConverterTest.java | 64 ++ .../converter/StringToBooleanConverterTest.java | 82 +++ .../data/converter/StringToByteConverterTest.java | 76 ++ .../converter/StringToCollectionConverterTest.java | 172 +++++ .../data/converter/StringToDateConverterTest.java | 32 + .../converter/StringToDoubleConverterTest.java | 29 + .../data/converter/StringToEnumConverterTest.java | 135 ++++ .../data/converter/StringToFloatConverterTest.java | 29 + .../converter/StringToIntegerConverterTest.java | 48 ++ .../data/converter/StringToLongConverterTest.java | 78 ++ .../data/converter/StringToShortConverterTest.java | 76 ++ .../vaadin/v7/tests/server/EventRouterTest.java | 40 + .../tests/server/PropertysetItemListenersTest.java | 14 + .../AbsFieldDataSourceLocaleChangeTest.java | 65 ++ .../abstractfield/AbsFieldValidatorsTest.java | 79 ++ .../AbsFieldValueConversionErrorTest.java | 92 +++ .../AbsFieldValueConversionsTest.java | 216 ++++++ .../AbstractFieldDeclarativeTest.java | 65 ++ .../abstractfield/AbstractFieldReadOnlyTest.java | 51 ++ .../abstractfield/DefaultConverterFactoryTest.java | 138 ++++ .../abstractfield/RemoveListenersOnDetachTest.java | 106 +++ .../AbstractTextFieldListenersTest.java | 34 + .../server/component/textfield/TextFieldTest.java | 50 ++ .../textfield/TextFieldValueChangeTest.java | 131 ++++ .../main/java/com/vaadin/event/FieldEvents.java | 77 -- .../java/com/vaadin/v7/ui/AbstractTextField.java | 814 --------------------- .../src/main/java/com/vaadin/v7/ui/TextField.java | 151 ---- .../com/vaadin/tests/server/EventRouterTest.java | 40 - .../com/vaadin/tests/server/ExtensionTest.java | 2 +- .../abstractfield/AbsFieldValidatorsTest.java | 79 -- .../AbsFieldValueConversionErrorTest.java | 92 --- .../AbsFieldValueConversionsTest.java | 216 ------ .../AbstractFieldDeclarativeTest.java | 65 -- .../abstractfield/AbstractFieldReadOnlyTest.java | 51 -- .../abstractfield/DefaultConverterFactoryTest.java | 138 ---- .../abstractfield/RemoveListenersOnDetachTest.java | 106 --- .../AbstractTextFieldListenersTest.java | 34 - .../component/gridlayout/DefaultAlignmentTest.java | 2 +- .../orderedlayout/DefaultAlignmentTest.java | 2 +- .../components/TextFieldValueChangeTest.java | 130 ---- .../ui/AbsFieldDataSourceLocaleChangeTest.java | 63 -- .../src/test/java/com/vaadin/ui/TextFieldTest.java | 50 -- .../converter/AnyEnumToStringConverterTest.java | 129 ---- .../tests/data/converter/ConverterFactoryTest.java | 128 ---- .../data/converter/DateToLongConverterTest.java | 28 - .../data/converter/DateToSqlDateConverterTest.java | 28 - .../converter/DefaultConverterFactoryTest.java | 124 ---- .../SpecificEnumToStringConverterTest.java | 125 ---- .../converter/StringToBigDecimalConverterTest.java | 59 -- .../converter/StringToBigIntegerConverterTest.java | 64 -- .../converter/StringToBooleanConverterTest.java | 82 --- .../data/converter/StringToByteConverterTest.java | 76 -- .../converter/StringToCollectionConverterTest.java | 172 ----- .../data/converter/StringToDateConverterTest.java | 32 - .../converter/StringToDoubleConverterTest.java | 29 - .../data/converter/StringToEnumConverterTest.java | 135 ---- .../data/converter/StringToFloatConverterTest.java | 29 - .../converter/StringToIntegerConverterTest.java | 48 -- .../data/converter/StringToLongConverterTest.java | 78 -- .../data/converter/StringToShortConverterTest.java | 76 -- .../abstractfield/LegacyAbstractTextFieldTest.java | 256 ------- .../passwordfield/PasswordFieldTest.java | 21 - .../textarea/TextAreaCursorPosition.java | 49 -- .../tests/components/textarea/TextAreaTest.java | 45 -- .../components/textfield/TextChangeEvents.java | 146 ---- .../components/textfield/TextChangeEvents2.java | 189 ----- .../textfield/TextChangeEventsEternalLoop.java | 26 - ...extChangeEventsWithNonImmediateValueChange.java | 57 -- ...extChangeListenerChangingNonTextProperties.java | 52 -- .../textfield/TextChangeListenerLosesFocus.java | 70 -- .../textfield/TextChangeTimeoutAfterDetach.java | 50 -- .../textfield/TextFieldEagerRepaint.java | 55 -- .../tests/components/textfield/TextFieldTest.java | 20 - .../passwordfield/PasswordFieldTest.java | 21 + .../textarea/TextAreaCursorPosition.java | 49 ++ .../v7/tests/components/textarea/TextAreaTest.java | 45 ++ .../textfield/AbstractTextFieldTest.java | 255 +++++++ .../components/textfield/TextChangeEvents.java | 146 ++++ .../components/textfield/TextChangeEvents2.java | 189 +++++ .../textfield/TextChangeEventsEternalLoop.java | 26 + ...extChangeEventsWithNonImmediateValueChange.java | 57 ++ ...extChangeListenerChangingNonTextProperties.java | 52 ++ .../textfield/TextChangeListenerLosesFocus.java | 70 ++ .../textfield/TextChangeTimeoutAfterDetach.java | 50 ++ .../textfield/TextFieldEagerRepaint.java | 55 ++ .../tests/components/textfield/TextFieldTest.java | 19 + 110 files changed, 5344 insertions(+), 5316 deletions(-) delete mode 100644 client/src/main/java/com/vaadin/client/v7/ui/VLegacyPasswordField.java delete mode 100644 client/src/main/java/com/vaadin/client/v7/ui/VLegacyTextField.java delete mode 100644 client/src/main/java/com/vaadin/client/v7/ui/textfield/LegacyTextFieldConnector.java create mode 100644 compatibility-client/src/main/java/com/vaadin/v7/client/ui/VPasswordField.java create mode 100644 compatibility-client/src/main/java/com/vaadin/v7/client/ui/VTextField.java create mode 100644 compatibility-client/src/main/java/com/vaadin/v7/client/ui/textfield/TextFieldConnector.java create mode 100644 compatibility-server/src/main/java/com/vaadin/v7/event/FieldEvents.java create mode 100644 compatibility-server/src/main/java/com/vaadin/v7/ui/AbstractTextField.java create mode 100644 compatibility-server/src/main/java/com/vaadin/v7/ui/TextField.java delete mode 100644 compatibility-server/src/test/java/com/vaadin/tests/server/PropertysetItemListenersTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/AnyEnumToStringConverterTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/ConverterFactoryTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/DateToLongConverterTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/DateToSqlDateConverterTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/DefaultConverterFactoryTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/SpecificEnumToStringConverterTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToBigDecimalConverterTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToBigIntegerConverterTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToBooleanConverterTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToByteConverterTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToCollectionConverterTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToDateConverterTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToDoubleConverterTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToEnumConverterTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToFloatConverterTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToIntegerConverterTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToLongConverterTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToShortConverterTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/server/EventRouterTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/server/PropertysetItemListenersTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbsFieldDataSourceLocaleChangeTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbsFieldValidatorsTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbsFieldValueConversionErrorTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbsFieldValueConversionsTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbstractFieldDeclarativeTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbstractFieldReadOnlyTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/DefaultConverterFactoryTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/RemoveListenersOnDetachTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstracttextfield/AbstractTextFieldListenersTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/textfield/TextFieldTest.java create mode 100644 compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/textfield/TextFieldValueChangeTest.java delete mode 100644 server/src/main/java/com/vaadin/v7/ui/AbstractTextField.java delete mode 100644 server/src/main/java/com/vaadin/v7/ui/TextField.java delete mode 100644 server/src/test/java/com/vaadin/tests/server/EventRouterTest.java delete mode 100644 server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbsFieldValidatorsTest.java delete mode 100644 server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversionErrorTest.java delete mode 100644 server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversionsTest.java delete mode 100644 server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbstractFieldDeclarativeTest.java delete mode 100644 server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbstractFieldReadOnlyTest.java delete mode 100644 server/src/test/java/com/vaadin/tests/server/component/abstractfield/DefaultConverterFactoryTest.java delete mode 100644 server/src/test/java/com/vaadin/tests/server/component/abstractfield/RemoveListenersOnDetachTest.java delete mode 100644 server/src/test/java/com/vaadin/tests/server/component/abstracttextfield/AbstractTextFieldListenersTest.java delete mode 100644 server/src/test/java/com/vaadin/tests/server/components/TextFieldValueChangeTest.java delete mode 100644 server/src/test/java/com/vaadin/ui/AbsFieldDataSourceLocaleChangeTest.java delete mode 100644 server/src/test/java/com/vaadin/ui/TextFieldTest.java delete mode 100644 server/src/test/java/com/vaadin/v7/tests/data/converter/AnyEnumToStringConverterTest.java delete mode 100644 server/src/test/java/com/vaadin/v7/tests/data/converter/ConverterFactoryTest.java delete mode 100644 server/src/test/java/com/vaadin/v7/tests/data/converter/DateToLongConverterTest.java delete mode 100644 server/src/test/java/com/vaadin/v7/tests/data/converter/DateToSqlDateConverterTest.java delete mode 100644 server/src/test/java/com/vaadin/v7/tests/data/converter/DefaultConverterFactoryTest.java delete mode 100644 server/src/test/java/com/vaadin/v7/tests/data/converter/SpecificEnumToStringConverterTest.java delete mode 100644 server/src/test/java/com/vaadin/v7/tests/data/converter/StringToBigDecimalConverterTest.java delete mode 100644 server/src/test/java/com/vaadin/v7/tests/data/converter/StringToBigIntegerConverterTest.java delete mode 100644 server/src/test/java/com/vaadin/v7/tests/data/converter/StringToBooleanConverterTest.java delete mode 100644 server/src/test/java/com/vaadin/v7/tests/data/converter/StringToByteConverterTest.java delete mode 100644 server/src/test/java/com/vaadin/v7/tests/data/converter/StringToCollectionConverterTest.java delete mode 100644 server/src/test/java/com/vaadin/v7/tests/data/converter/StringToDateConverterTest.java delete mode 100644 server/src/test/java/com/vaadin/v7/tests/data/converter/StringToDoubleConverterTest.java delete mode 100644 server/src/test/java/com/vaadin/v7/tests/data/converter/StringToEnumConverterTest.java delete mode 100644 server/src/test/java/com/vaadin/v7/tests/data/converter/StringToFloatConverterTest.java delete mode 100644 server/src/test/java/com/vaadin/v7/tests/data/converter/StringToIntegerConverterTest.java delete mode 100644 server/src/test/java/com/vaadin/v7/tests/data/converter/StringToLongConverterTest.java delete mode 100644 server/src/test/java/com/vaadin/v7/tests/data/converter/StringToShortConverterTest.java delete mode 100644 uitest/src/main/java/com/vaadin/tests/components/abstractfield/LegacyAbstractTextFieldTest.java delete mode 100644 uitest/src/main/java/com/vaadin/tests/components/passwordfield/PasswordFieldTest.java delete mode 100644 uitest/src/main/java/com/vaadin/tests/components/textarea/TextAreaCursorPosition.java delete mode 100644 uitest/src/main/java/com/vaadin/tests/components/textarea/TextAreaTest.java delete mode 100644 uitest/src/main/java/com/vaadin/tests/components/textfield/TextChangeEvents.java delete mode 100644 uitest/src/main/java/com/vaadin/tests/components/textfield/TextChangeEvents2.java delete mode 100644 uitest/src/main/java/com/vaadin/tests/components/textfield/TextChangeEventsEternalLoop.java delete mode 100644 uitest/src/main/java/com/vaadin/tests/components/textfield/TextChangeEventsWithNonImmediateValueChange.java delete mode 100644 uitest/src/main/java/com/vaadin/tests/components/textfield/TextChangeListenerChangingNonTextProperties.java delete mode 100644 uitest/src/main/java/com/vaadin/tests/components/textfield/TextChangeListenerLosesFocus.java delete mode 100644 uitest/src/main/java/com/vaadin/tests/components/textfield/TextChangeTimeoutAfterDetach.java delete mode 100644 uitest/src/main/java/com/vaadin/tests/components/textfield/TextFieldEagerRepaint.java delete mode 100644 uitest/src/main/java/com/vaadin/tests/components/textfield/TextFieldTest.java create mode 100644 uitest/src/main/java/com/vaadin/v7/tests/components/passwordfield/PasswordFieldTest.java create mode 100644 uitest/src/main/java/com/vaadin/v7/tests/components/textarea/TextAreaCursorPosition.java create mode 100644 uitest/src/main/java/com/vaadin/v7/tests/components/textarea/TextAreaTest.java create mode 100644 uitest/src/main/java/com/vaadin/v7/tests/components/textfield/AbstractTextFieldTest.java create mode 100644 uitest/src/main/java/com/vaadin/v7/tests/components/textfield/TextChangeEvents.java create mode 100644 uitest/src/main/java/com/vaadin/v7/tests/components/textfield/TextChangeEvents2.java create mode 100644 uitest/src/main/java/com/vaadin/v7/tests/components/textfield/TextChangeEventsEternalLoop.java create mode 100644 uitest/src/main/java/com/vaadin/v7/tests/components/textfield/TextChangeEventsWithNonImmediateValueChange.java create mode 100644 uitest/src/main/java/com/vaadin/v7/tests/components/textfield/TextChangeListenerChangingNonTextProperties.java create mode 100644 uitest/src/main/java/com/vaadin/v7/tests/components/textfield/TextChangeListenerLosesFocus.java create mode 100644 uitest/src/main/java/com/vaadin/v7/tests/components/textfield/TextChangeTimeoutAfterDetach.java create mode 100644 uitest/src/main/java/com/vaadin/v7/tests/components/textfield/TextFieldEagerRepaint.java create mode 100644 uitest/src/main/java/com/vaadin/v7/tests/components/textfield/TextFieldTest.java diff --git a/client/src/main/java/com/vaadin/client/ui/VTextualDate.java b/client/src/main/java/com/vaadin/client/ui/VTextualDate.java index b6788d8516..45221dfce0 100644 --- a/client/src/main/java/com/vaadin/client/ui/VTextualDate.java +++ b/client/src/main/java/com/vaadin/client/ui/VTextualDate.java @@ -38,7 +38,6 @@ import com.vaadin.client.ui.aria.AriaHelper; import com.vaadin.client.ui.aria.HandlesAriaCaption; import com.vaadin.client.ui.aria.HandlesAriaInvalid; import com.vaadin.client.ui.aria.HandlesAriaRequired; -import com.vaadin.client.v7.ui.VLegacyTextField; import com.vaadin.shared.EventId; import com.vaadin.shared.ui.datefield.Resolution; @@ -74,8 +73,8 @@ public class VTextualDate extends VDateField implements Field, ChangeHandler, text.addFocusHandler(new FocusHandler() { @Override public void onFocus(FocusEvent event) { - text.addStyleName(VLegacyTextField.CLASSNAME + "-" - + VLegacyTextField.CLASSNAME_FOCUS); + text.addStyleName(VTextField.CLASSNAME + "-" + + VTextField.CLASSNAME_FOCUS); if (prompting) { text.setText(""); setPrompting(false); @@ -93,8 +92,8 @@ public class VTextualDate extends VDateField implements Field, ChangeHandler, text.addBlurHandler(new BlurHandler() { @Override public void onBlur(BlurEvent event) { - text.removeStyleName(VLegacyTextField.CLASSNAME + "-" - + VLegacyTextField.CLASSNAME_FOCUS); + text.removeStyleName(VTextField.CLASSNAME + "-" + + VTextField.CLASSNAME_FOCUS); String value = getText(); setPrompting(inputPrompt != null && (value == null || "".equals(value))); @@ -118,7 +117,7 @@ public class VTextualDate extends VDateField implements Field, ChangeHandler, protected void updateStyleNames() { if (text != null) { - text.setStyleName(VLegacyTextField.CLASSNAME); + text.setStyleName(VTextField.CLASSNAME); text.addStyleName(getStylePrimaryName() + "-textfield"); } } @@ -364,8 +363,8 @@ public class VTextualDate extends VDateField implements Field, ChangeHandler, protected void setText(String text) { if (inputPrompt != null && (text == null || "".equals(text)) - && !this.text.getStyleName().contains(VLegacyTextField.CLASSNAME - + "-" + VLegacyTextField.CLASSNAME_FOCUS)) { + && !this.text.getStyleName().contains(VTextField.CLASSNAME + "-" + + VTextField.CLASSNAME_FOCUS)) { text = readonly ? "" : inputPrompt; setPrompting(true); } else { diff --git a/client/src/main/java/com/vaadin/client/v7/ui/VLegacyPasswordField.java b/client/src/main/java/com/vaadin/client/v7/ui/VLegacyPasswordField.java deleted file mode 100644 index ffc1422eb0..0000000000 --- a/client/src/main/java/com/vaadin/client/v7/ui/VLegacyPasswordField.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * Licensed 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 com.vaadin.client.v7.ui; - -import com.google.gwt.user.client.DOM; - -/** - * This class represents a password field. - * - * @author Vaadin Ltd. - * - */ -@Deprecated -public class VLegacyPasswordField extends VLegacyTextField { - - public VLegacyPasswordField() { - super(DOM.createInputPassword()); - } - -} diff --git a/client/src/main/java/com/vaadin/client/v7/ui/VLegacyTextField.java b/client/src/main/java/com/vaadin/client/v7/ui/VLegacyTextField.java deleted file mode 100644 index 5768311960..0000000000 --- a/client/src/main/java/com/vaadin/client/v7/ui/VLegacyTextField.java +++ /dev/null @@ -1,533 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * Licensed 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 com.vaadin.client.v7.ui; - -import com.google.gwt.core.client.Scheduler; -import com.google.gwt.core.client.Scheduler.ScheduledCommand; -import com.google.gwt.dom.client.Element; -import com.google.gwt.event.dom.client.BlurEvent; -import com.google.gwt.event.dom.client.BlurHandler; -import com.google.gwt.event.dom.client.ChangeEvent; -import com.google.gwt.event.dom.client.ChangeHandler; -import com.google.gwt.event.dom.client.FocusEvent; -import com.google.gwt.event.dom.client.FocusHandler; -import com.google.gwt.event.dom.client.KeyCodes; -import com.google.gwt.event.dom.client.KeyDownEvent; -import com.google.gwt.event.dom.client.KeyDownHandler; -import com.google.gwt.user.client.DOM; -import com.google.gwt.user.client.Event; -import com.google.gwt.user.client.Timer; -import com.google.gwt.user.client.ui.TextBoxBase; -import com.vaadin.client.ApplicationConnection; -import com.vaadin.client.BrowserInfo; -import com.vaadin.client.WidgetUtil; -import com.vaadin.client.ui.Field; -import com.vaadin.shared.EventId; -import com.vaadin.shared.v7.ui.textfield.LegacyTextFieldConstants; - -/** - * This class represents a basic text input field with one row. - * - * @author Vaadin Ltd. - * - */ -@Deprecated -public class VLegacyTextField extends TextBoxBase implements Field, - ChangeHandler, FocusHandler, BlurHandler, KeyDownHandler { - - /** - * The input node CSS classname. - */ - public static final String CLASSNAME = "v-textfield"; - /** - * This CSS classname is added to the input node on hover. - */ - public static final String CLASSNAME_FOCUS = "focus"; - - /** For internal use only. May be removed or replaced in the future. */ - public String paintableId; - - /** For internal use only. May be removed or replaced in the future. */ - public ApplicationConnection client; - - /** For internal use only. May be removed or replaced in the future. */ - public String valueBeforeEdit = null; - - /** - * Set to false if a text change event has been sent since the last value - * change event. This means that {@link #valueBeforeEdit} should not be - * trusted when determining whether a text change even should be sent. - */ - private boolean valueBeforeEditIsSynced = true; - - private boolean immediate = false; - private int maxLength = -1; - - private static final String CLASSNAME_PROMPT = "prompt"; - private static final String TEXTCHANGE_MODE_TIMEOUT = "TIMEOUT"; - - private String inputPrompt = null; - private boolean prompting = false; - private int lastCursorPos = -1; - - // used while checking if FF has set input prompt as value - private boolean possibleInputError = false; - - public VLegacyTextField() { - this(DOM.createInputText()); - } - - protected VLegacyTextField(Element node) { - super(node); - setStyleName(CLASSNAME); - addChangeHandler(this); - if (BrowserInfo.get().isIE() || BrowserInfo.get().isFirefox()) { - addKeyDownHandler(this); - } - addFocusHandler(this); - addBlurHandler(this); - } - - /** - * For internal use only. May be removed or replaced in the future. - *

- * TODO When GWT adds ONCUT, add it there and remove workaround. See - * http://code.google.com/p/google-web-toolkit/issues/detail?id=4030 - *

- * Also note that the cut/paste are not totally crossbrowsers compatible. - * E.g. in Opera mac works via context menu, but on via File->Paste/Cut. - * Opera might need the polling method for 100% working textchanceevents. - * Eager polling for a change is bit dum and heavy operation, so I guess we - * should first try to survive without. - */ - public static final int TEXTCHANGE_EVENTS = Event.ONPASTE | Event.KEYEVENTS - | Event.ONMOUSEUP; - - @Override - public void onBrowserEvent(Event event) { - super.onBrowserEvent(event); - - if (listenTextChangeEvents - && (event.getTypeInt() & TEXTCHANGE_EVENTS) == event - .getTypeInt()) { - deferTextChangeEvent(); - } - - } - - /* - * TODO optimize this so that only changes are sent + make the value change - * event just a flag that moves the current text to value - */ - private String lastTextChangeString = null; - - private String getLastCommunicatedString() { - return lastTextChangeString; - } - - private void communicateTextValueToServer() { - String text = getText(); - if (prompting) { - // Input prompt visible, text is actually "" - text = ""; - } - if (!text.equals(getLastCommunicatedString())) { - if (valueBeforeEditIsSynced && text.equals(valueBeforeEdit)) { - /* - * Value change for the current text has been enqueued since the - * last text change event was sent, but we can't know that it - * has been sent to the server. Ensure that all pending changes - * are sent now. Sending a value change without a text change - * will simulate a TextChangeEvent on the server. - */ - client.sendPendingVariableChanges(); - } else { - // Default case - just send an immediate text change message - client.updateVariable(paintableId, - LegacyTextFieldConstants.VAR_CUR_TEXT, text, true); - - // Shouldn't investigate valueBeforeEdit to avoid duplicate text - // change events as the states are not in sync any more - valueBeforeEditIsSynced = false; - } - lastTextChangeString = text; - } - } - - private Timer textChangeEventTrigger = new Timer() { - - @Override - public void run() { - if (isAttached()) { - updateCursorPosition(); - communicateTextValueToServer(); - scheduled = false; - } - } - }; - - private boolean scheduled = false; - - /** For internal use only. May be removed or replaced in the future. */ - public boolean listenTextChangeEvents; - /** For internal use only. May be removed or replaced in the future. */ - public String textChangeEventMode; - public int textChangeEventTimeout; - - private void deferTextChangeEvent() { - if (textChangeEventMode.equals(TEXTCHANGE_MODE_TIMEOUT) && scheduled) { - return; - } else { - textChangeEventTrigger.cancel(); - } - textChangeEventTrigger.schedule(getTextChangeEventTimeout()); - scheduled = true; - } - - private int getTextChangeEventTimeout() { - return textChangeEventTimeout; - } - - @Override - public void setReadOnly(boolean readOnly) { - boolean wasReadOnly = isReadOnly(); - - if (readOnly) { - setTabIndex(-1); - } else if (wasReadOnly && !readOnly && getTabIndex() == -1) { - /* - * Need to manually set tab index to 0 since server will not send - * the tab index if it is 0. - */ - setTabIndex(0); - } - - super.setReadOnly(readOnly); - } - - /** For internal use only. May be removed or replaced in the future. */ - public void updateFieldContent(final String text) { - setPrompting(inputPrompt != null && focusedTextField != this - && (text.equals(""))); - - String fieldValue; - if (prompting) { - fieldValue = isReadOnly() ? "" : inputPrompt; - addStyleDependentName(CLASSNAME_PROMPT); - } else { - fieldValue = text; - removeStyleDependentName(CLASSNAME_PROMPT); - } - setText(fieldValue); - - lastTextChangeString = valueBeforeEdit = text; - valueBeforeEditIsSynced = true; - } - - protected void onCut() { - if (listenTextChangeEvents) { - deferTextChangeEvent(); - } - } - - /** For internal use only. May be removed or replaced in the future. */ - public native void attachCutEventListener(Element el) - /*-{ - var me = this; - el.oncut = $entry(function() { - me.@com.vaadin.client.v7.ui.VLegacyTextField::onCut()(); - }); - }-*/; - - protected native void detachCutEventListener(Element el) - /*-{ - el.oncut = null; - }-*/; - - private void onDrop() { - if (focusedTextField == this) { - return; - } - updateText(false); - } - - private void updateText(boolean blurred) { - String text = getText(); - setPrompting(inputPrompt != null && (text == null || text.isEmpty())); - if (prompting) { - setText(isReadOnly() ? "" : inputPrompt); - if (blurred) { - addStyleDependentName(CLASSNAME_PROMPT); - } - } - - valueChange(blurred); - } - - private void scheduleOnDropEvent() { - Scheduler.get().scheduleDeferred(new ScheduledCommand() { - @Override - public void execute() { - onDrop(); - } - }); - } - - private native void attachDropEventListener(Element el) - /*-{ - var me = this; - el.ondrop = $entry(function() { - me.@com.vaadin.client.v7.ui.VLegacyTextField::scheduleOnDropEvent()(); - }); - }-*/; - - private native void detachDropEventListener(Element el) - /*-{ - el.ondrop = null; - }-*/; - - @Override - protected void onDetach() { - super.onDetach(); - detachCutEventListener(getElement()); - if (focusedTextField == this) { - focusedTextField = null; - } - if (BrowserInfo.get().isFirefox()) { - removeOnInputListener(getElement()); - detachDropEventListener(getElement()); - } - } - - @Override - protected void onAttach() { - super.onAttach(); - if (listenTextChangeEvents) { - detachCutEventListener(getElement()); - } - if (BrowserInfo.get().isFirefox()) { - // Workaround for FF setting input prompt as the value if esc is - // pressed while the field is focused and empty (#8051). - addOnInputListener(getElement()); - // Workaround for FF updating component's internal value after - // having drag-and-dropped text from another element (#14056) - attachDropEventListener(getElement()); - } - } - - /** For internal use only. May be removed or replaced in the future. */ - public void setMaxLength(int newMaxLength) { - if (newMaxLength == maxLength) { - return; - } - maxLength = newMaxLength; - updateMaxLength(maxLength); - } - - /** - * This method is responsible for updating the DOM or otherwise ensuring - * that the given max length is enforced. Called when the max length for the - * field has changed. - * - * @param maxLength - * The new max length - */ - protected void updateMaxLength(int maxLength) { - if (maxLength >= 0) { - getElement().setPropertyInt("maxLength", maxLength); - } else { - getElement().removeAttribute("maxLength"); - - } - setMaxLengthToElement(maxLength); - } - - protected void setMaxLengthToElement(int newMaxLength) { - if (newMaxLength >= 0) { - getElement().setPropertyInt("maxLength", newMaxLength); - } else { - getElement().removeAttribute("maxLength"); - } - } - - public int getMaxLength() { - return maxLength; - } - - @Override - public void onChange(ChangeEvent event) { - valueChange(false); - } - - /** - * Called when the field value might have changed and/or the field was - * blurred. These are combined so the blur event is sent in the same batch - * as a possible value change event (these are often connected). - * - * @param blurred - * true if the field was blurred - */ - public void valueChange(boolean blurred) { - if (client != null && paintableId != null) { - boolean sendBlurEvent = false; - boolean sendValueChange = false; - - if (blurred && client.hasEventListeners(this, EventId.BLUR)) { - sendBlurEvent = true; - client.updateVariable(paintableId, EventId.BLUR, "", false); - } - - String newText = prompting ? "" : getText(); - if (newText != null && !newText.equals(valueBeforeEdit)) { - sendValueChange = immediate; - client.updateVariable(paintableId, "text", newText, false); - valueBeforeEdit = newText; - valueBeforeEditIsSynced = true; - } - - /* - * also send cursor position, no public api yet but for easier - * extension - */ - updateCursorPosition(); - - if (sendBlurEvent || sendValueChange) { - /* - * Avoid sending text change event as we will simulate it on the - * server side before value change events. - */ - textChangeEventTrigger.cancel(); - scheduled = false; - client.sendPendingVariableChanges(); - } - } - } - - /** - * Updates the cursor position variable if it has changed since the last - * update. - * - * @return true iff the value was updated - */ - protected boolean updateCursorPosition() { - if (WidgetUtil.isAttachedAndDisplayed(this)) { - int cursorPos = prompting ? 0 : getCursorPos(); - if (lastCursorPos != cursorPos) { - client.updateVariable(paintableId, - LegacyTextFieldConstants.VAR_CURSOR, cursorPos, false); - lastCursorPos = cursorPos; - return true; - } - } - return false; - } - - private static VLegacyTextField focusedTextField; - - public static void flushChangesFromFocusedTextField() { - if (focusedTextField != null) { - focusedTextField.onChange(null); - } - } - - @Override - public void onFocus(FocusEvent event) { - addStyleDependentName(CLASSNAME_FOCUS); - if (prompting) { - setText(""); - removeStyleDependentName(CLASSNAME_PROMPT); - setPrompting(false); - } - focusedTextField = this; - if (client != null && client.hasEventListeners(this, EventId.FOCUS)) { - client.updateVariable(paintableId, EventId.FOCUS, "", true); - } - } - - @Override - public void onBlur(BlurEvent event) { - // this is called twice on Chrome when e.g. changing tab while prompting - // field focused - do not change settings on the second time - if (focusedTextField != this) { - return; - } - removeStyleDependentName(CLASSNAME_FOCUS); - focusedTextField = null; - updateText(true); - } - - private void setPrompting(boolean prompting) { - this.prompting = prompting; - } - - public void setColumns(int columns) { - if (columns <= 0) { - return; - } - - setWidth(columns + "em"); - } - - @Override - public void onKeyDown(KeyDownEvent event) { - if (BrowserInfo.get().isIE() - && event.getNativeKeyCode() == KeyCodes.KEY_ENTER) { - // IE does not send change events when pressing enter in a text - // input so we handle it using a key listener instead - valueChange(false); - } else if (BrowserInfo.get().isFirefox() - && event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE - && getText().equals("")) { - // check after onInput event if inputPrompt has appeared as the - // value of the field - possibleInputError = true; - } - } - - public void setImmediate(boolean immediate) { - this.immediate = immediate; - } - - public void setInputPrompt(String inputPrompt) { - this.inputPrompt = inputPrompt; - } - - protected boolean isWordwrap() { - String wrap = getElement().getAttribute("wrap"); - return !"off".equals(wrap); - } - - private native void addOnInputListener(Element el) - /*-{ - var self = this; - el.oninput = $entry(function() { - self.@com.vaadin.client.v7.ui.VLegacyTextField::checkForInputError()(); - }); - }-*/; - - private native void removeOnInputListener(Element el) - /*-{ - el.oninput = null; - }-*/; - - private void checkForInputError() { - if (possibleInputError && getText().equals(inputPrompt)) { - setText(""); - } - possibleInputError = false; - } -} diff --git a/client/src/main/java/com/vaadin/client/v7/ui/textfield/LegacyTextFieldConnector.java b/client/src/main/java/com/vaadin/client/v7/ui/textfield/LegacyTextFieldConnector.java deleted file mode 100644 index 92ae3a47da..0000000000 --- a/client/src/main/java/com/vaadin/client/v7/ui/textfield/LegacyTextFieldConnector.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * Licensed 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 com.vaadin.client.v7.ui.textfield; - -import com.google.gwt.core.client.Scheduler; -import com.google.gwt.user.client.Command; -import com.vaadin.client.ApplicationConnection; -import com.vaadin.client.Paintable; -import com.vaadin.client.UIDL; -import com.vaadin.client.Util; -import com.vaadin.client.ui.AbstractFieldConnector; -import com.vaadin.client.v7.ui.VLegacyTextField; -import com.vaadin.shared.ui.Connect; -import com.vaadin.shared.ui.Connect.LoadStyle; -import com.vaadin.shared.v7.ui.textfield.LegacyAbstractTextFieldState; -import com.vaadin.shared.v7.ui.textfield.LegacyTextFieldConstants; -import com.vaadin.v7.ui.TextField; - -@Deprecated -@Connect(value = TextField.class, loadStyle = LoadStyle.EAGER) -public class LegacyTextFieldConnector extends AbstractFieldConnector - implements Paintable { - - @Override - public LegacyAbstractTextFieldState getState() { - return (LegacyAbstractTextFieldState) super.getState(); - } - - @Override - public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { - // Save details - getWidget().client = client; - getWidget().paintableId = uidl.getId(); - - if (!isRealUpdate(uidl)) { - return; - } - - getWidget().setReadOnly(isReadOnly()); - - getWidget().setInputPrompt(getState().inputPrompt); - getWidget().setMaxLength(getState().maxLength); - getWidget().setImmediate(getState().immediate); - - getWidget().listenTextChangeEvents = hasEventListener("ie"); - if (getWidget().listenTextChangeEvents) { - getWidget().textChangeEventMode = uidl.getStringAttribute( - LegacyTextFieldConstants.ATTR_TEXTCHANGE_EVENTMODE); - if (getWidget().textChangeEventMode - .equals(LegacyTextFieldConstants.TEXTCHANGE_MODE_EAGER)) { - getWidget().textChangeEventTimeout = 1; - } else { - getWidget().textChangeEventTimeout = uidl.getIntAttribute( - LegacyTextFieldConstants.ATTR_TEXTCHANGE_TIMEOUT); - if (getWidget().textChangeEventTimeout < 1) { - // Sanitize and allow lazy/timeout with timeout set to 0 to - // work as eager - getWidget().textChangeEventTimeout = 1; - } - } - getWidget().sinkEvents(VLegacyTextField.TEXTCHANGE_EVENTS); - getWidget().attachCutEventListener(getWidget().getElement()); - } - getWidget().setColumns(getState().columns); - - String text = getState().text; - if (text == null) { - text = ""; - } - /* - * We skip the text content update if field has been repainted, but text - * has not been changed (#6588). Additional sanity check verifies there - * is no change in the queue (in which case we count more on the server - * side value). is updated only when it looses focus, so we - * force updating if not focused. Lost focus issue appeared in (#15144) - */ - if (!(Util.getFocusedElement() == getWidget().getElement()) - || !uidl.getBooleanAttribute( - LegacyTextFieldConstants.ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS) - || getWidget().valueBeforeEdit == null - || !text.equals(getWidget().valueBeforeEdit)) { - getWidget().updateFieldContent(text); - } - - if (uidl.hasAttribute("selpos")) { - final int pos = uidl.getIntAttribute("selpos"); - final int length = uidl.getIntAttribute("sellen"); - /* - * Gecko defers setting the text so we need to defer the selection. - */ - Scheduler.get().scheduleDeferred(new Command() { - @Override - public void execute() { - getWidget().setSelectionRange(pos, length); - } - }); - } - } - - @Override - public VLegacyTextField getWidget() { - return (VLegacyTextField) super.getWidget(); - } - - @Override - public void flush() { - getWidget().valueChange(false); - } - -} diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VOptionGroupBase.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VOptionGroupBase.java index 596828ecd5..94a92e2980 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VOptionGroupBase.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VOptionGroupBase.java @@ -35,7 +35,6 @@ import com.vaadin.client.Focusable; import com.vaadin.client.UIDL; import com.vaadin.client.ui.Field; import com.vaadin.client.ui.VNativeButton; -import com.vaadin.client.v7.ui.VLegacyTextField; public abstract class VOptionGroupBase extends Composite implements Field, ClickHandler, ChangeHandler, KeyPressHandler, Focusable, HasEnabled { @@ -86,7 +85,7 @@ public abstract class VOptionGroupBase extends Composite implements Field, public final Panel container; /** For internal use only. May be removed or replaced in the future. */ - public VLegacyTextField newItemField; + public VTextField newItemField; /** For internal use only. May be removed or replaced in the future. */ public VNativeButton newItemButton; diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VPasswordField.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VPasswordField.java new file mode 100644 index 0000000000..f565b8a9a0 --- /dev/null +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VPasswordField.java @@ -0,0 +1,34 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed 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 com.vaadin.v7.client.ui; + +import com.google.gwt.user.client.DOM; + +/** + * This class represents a password field. + * + * @author Vaadin Ltd. + * + */ +@Deprecated +public class VPasswordField extends VTextField { + + public VPasswordField() { + super(DOM.createInputPassword()); + } + +} diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VScrollTable.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VScrollTable.java index d15ae0b9fa..252f78ca86 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VScrollTable.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VScrollTable.java @@ -111,7 +111,6 @@ import com.vaadin.client.ui.dd.VDragAndDropManager; import com.vaadin.client.ui.dd.VDragEvent; import com.vaadin.client.ui.dd.VHasDropHandler; import com.vaadin.client.ui.dd.VTransferable; -import com.vaadin.client.v7.ui.VLegacyTextField; import com.vaadin.shared.AbstractComponentState; import com.vaadin.shared.MouseEventDetails; import com.vaadin.shared.ui.dd.VerticalDropLocation; @@ -6494,8 +6493,8 @@ public class VScrollTable extends FlowPanel if (!(widget instanceof VLabel) && !(widget instanceof VEmbedded) - && !(widget instanceof VLegacyTextField - && ((VLegacyTextField) widget) + && !(widget instanceof VTextField + && ((VTextField) widget) .isReadOnly())) { return null; } diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VTextArea.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VTextArea.java index 38f538fbdf..c5d229e153 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VTextArea.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VTextArea.java @@ -33,7 +33,6 @@ import com.google.gwt.user.client.Event; import com.vaadin.client.BrowserInfo; import com.vaadin.client.WidgetUtil; import com.vaadin.client.ui.dd.DragImageModifier; -import com.vaadin.client.v7.ui.VLegacyTextField; /** * This class represents a multiline textfield (textarea). @@ -45,7 +44,7 @@ import com.vaadin.client.v7.ui.VLegacyTextField; * */ @Deprecated -public class VTextArea extends VLegacyTextField implements DragImageModifier { +public class VTextArea extends VTextField implements DragImageModifier { public static final String CLASSNAME = "v-textarea"; private boolean wordwrap = true; diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VTextField.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VTextField.java new file mode 100644 index 0000000000..9fb529ff20 --- /dev/null +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VTextField.java @@ -0,0 +1,533 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed 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 com.vaadin.v7.client.ui; + +import com.google.gwt.core.client.Scheduler; +import com.google.gwt.core.client.Scheduler.ScheduledCommand; +import com.google.gwt.dom.client.Element; +import com.google.gwt.event.dom.client.BlurEvent; +import com.google.gwt.event.dom.client.BlurHandler; +import com.google.gwt.event.dom.client.ChangeEvent; +import com.google.gwt.event.dom.client.ChangeHandler; +import com.google.gwt.event.dom.client.FocusEvent; +import com.google.gwt.event.dom.client.FocusHandler; +import com.google.gwt.event.dom.client.KeyCodes; +import com.google.gwt.event.dom.client.KeyDownEvent; +import com.google.gwt.event.dom.client.KeyDownHandler; +import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.Timer; +import com.google.gwt.user.client.ui.TextBoxBase; +import com.vaadin.client.ApplicationConnection; +import com.vaadin.client.BrowserInfo; +import com.vaadin.client.WidgetUtil; +import com.vaadin.client.ui.Field; +import com.vaadin.shared.EventId; +import com.vaadin.shared.v7.ui.textfield.LegacyTextFieldConstants; + +/** + * This class represents a basic text input field with one row. + * + * @author Vaadin Ltd. + * + */ +@Deprecated +public class VTextField extends TextBoxBase implements Field, ChangeHandler, + FocusHandler, BlurHandler, KeyDownHandler { + + /** + * The input node CSS classname. + */ + public static final String CLASSNAME = "v-textfield"; + /** + * This CSS classname is added to the input node on hover. + */ + public static final String CLASSNAME_FOCUS = "focus"; + + /** For internal use only. May be removed or replaced in the future. */ + public String paintableId; + + /** For internal use only. May be removed or replaced in the future. */ + public ApplicationConnection client; + + /** For internal use only. May be removed or replaced in the future. */ + public String valueBeforeEdit = null; + + /** + * Set to false if a text change event has been sent since the last value + * change event. This means that {@link #valueBeforeEdit} should not be + * trusted when determining whether a text change even should be sent. + */ + private boolean valueBeforeEditIsSynced = true; + + private boolean immediate = false; + private int maxLength = -1; + + private static final String CLASSNAME_PROMPT = "prompt"; + private static final String TEXTCHANGE_MODE_TIMEOUT = "TIMEOUT"; + + private String inputPrompt = null; + private boolean prompting = false; + private int lastCursorPos = -1; + + // used while checking if FF has set input prompt as value + private boolean possibleInputError = false; + + public VTextField() { + this(DOM.createInputText()); + } + + protected VTextField(Element node) { + super(node); + setStyleName(CLASSNAME); + addChangeHandler(this); + if (BrowserInfo.get().isIE() || BrowserInfo.get().isFirefox()) { + addKeyDownHandler(this); + } + addFocusHandler(this); + addBlurHandler(this); + } + + /** + * For internal use only. May be removed or replaced in the future. + *

+ * TODO When GWT adds ONCUT, add it there and remove workaround. See + * http://code.google.com/p/google-web-toolkit/issues/detail?id=4030 + *

+ * Also note that the cut/paste are not totally crossbrowsers compatible. + * E.g. in Opera mac works via context menu, but on via File->Paste/Cut. + * Opera might need the polling method for 100% working textchanceevents. + * Eager polling for a change is bit dum and heavy operation, so I guess we + * should first try to survive without. + */ + public static final int TEXTCHANGE_EVENTS = Event.ONPASTE | Event.KEYEVENTS + | Event.ONMOUSEUP; + + @Override + public void onBrowserEvent(Event event) { + super.onBrowserEvent(event); + + if (listenTextChangeEvents + && (event.getTypeInt() & TEXTCHANGE_EVENTS) == event + .getTypeInt()) { + deferTextChangeEvent(); + } + + } + + /* + * TODO optimize this so that only changes are sent + make the value change + * event just a flag that moves the current text to value + */ + private String lastTextChangeString = null; + + private String getLastCommunicatedString() { + return lastTextChangeString; + } + + private void communicateTextValueToServer() { + String text = getText(); + if (prompting) { + // Input prompt visible, text is actually "" + text = ""; + } + if (!text.equals(getLastCommunicatedString())) { + if (valueBeforeEditIsSynced && text.equals(valueBeforeEdit)) { + /* + * Value change for the current text has been enqueued since the + * last text change event was sent, but we can't know that it + * has been sent to the server. Ensure that all pending changes + * are sent now. Sending a value change without a text change + * will simulate a TextChangeEvent on the server. + */ + client.sendPendingVariableChanges(); + } else { + // Default case - just send an immediate text change message + client.updateVariable(paintableId, + LegacyTextFieldConstants.VAR_CUR_TEXT, text, true); + + // Shouldn't investigate valueBeforeEdit to avoid duplicate text + // change events as the states are not in sync any more + valueBeforeEditIsSynced = false; + } + lastTextChangeString = text; + } + } + + private Timer textChangeEventTrigger = new Timer() { + + @Override + public void run() { + if (isAttached()) { + updateCursorPosition(); + communicateTextValueToServer(); + scheduled = false; + } + } + }; + + private boolean scheduled = false; + + /** For internal use only. May be removed or replaced in the future. */ + public boolean listenTextChangeEvents; + /** For internal use only. May be removed or replaced in the future. */ + public String textChangeEventMode; + public int textChangeEventTimeout; + + private void deferTextChangeEvent() { + if (textChangeEventMode.equals(TEXTCHANGE_MODE_TIMEOUT) && scheduled) { + return; + } else { + textChangeEventTrigger.cancel(); + } + textChangeEventTrigger.schedule(getTextChangeEventTimeout()); + scheduled = true; + } + + private int getTextChangeEventTimeout() { + return textChangeEventTimeout; + } + + @Override + public void setReadOnly(boolean readOnly) { + boolean wasReadOnly = isReadOnly(); + + if (readOnly) { + setTabIndex(-1); + } else if (wasReadOnly && !readOnly && getTabIndex() == -1) { + /* + * Need to manually set tab index to 0 since server will not send + * the tab index if it is 0. + */ + setTabIndex(0); + } + + super.setReadOnly(readOnly); + } + + /** For internal use only. May be removed or replaced in the future. */ + public void updateFieldContent(final String text) { + setPrompting(inputPrompt != null && focusedTextField != this + && (text.equals(""))); + + String fieldValue; + if (prompting) { + fieldValue = isReadOnly() ? "" : inputPrompt; + addStyleDependentName(CLASSNAME_PROMPT); + } else { + fieldValue = text; + removeStyleDependentName(CLASSNAME_PROMPT); + } + setText(fieldValue); + + lastTextChangeString = valueBeforeEdit = text; + valueBeforeEditIsSynced = true; + } + + protected void onCut() { + if (listenTextChangeEvents) { + deferTextChangeEvent(); + } + } + + /** For internal use only. May be removed or replaced in the future. */ + public native void attachCutEventListener(Element el) + /*-{ + var me = this; + el.oncut = $entry(function() { + me.@com.vaadin.v7.client.ui.VTextField::onCut()(); + }); + }-*/; + + protected native void detachCutEventListener(Element el) + /*-{ + el.oncut = null; + }-*/; + + private void onDrop() { + if (focusedTextField == this) { + return; + } + updateText(false); + } + + private void updateText(boolean blurred) { + String text = getText(); + setPrompting(inputPrompt != null && (text == null || text.isEmpty())); + if (prompting) { + setText(isReadOnly() ? "" : inputPrompt); + if (blurred) { + addStyleDependentName(CLASSNAME_PROMPT); + } + } + + valueChange(blurred); + } + + private void scheduleOnDropEvent() { + Scheduler.get().scheduleDeferred(new ScheduledCommand() { + @Override + public void execute() { + onDrop(); + } + }); + } + + private native void attachDropEventListener(Element el) + /*-{ + var me = this; + el.ondrop = $entry(function() { + me.@com.vaadin.v7.client.ui.VTextField::scheduleOnDropEvent()(); + }); + }-*/; + + private native void detachDropEventListener(Element el) + /*-{ + el.ondrop = null; + }-*/; + + @Override + protected void onDetach() { + super.onDetach(); + detachCutEventListener(getElement()); + if (focusedTextField == this) { + focusedTextField = null; + } + if (BrowserInfo.get().isFirefox()) { + removeOnInputListener(getElement()); + detachDropEventListener(getElement()); + } + } + + @Override + protected void onAttach() { + super.onAttach(); + if (listenTextChangeEvents) { + detachCutEventListener(getElement()); + } + if (BrowserInfo.get().isFirefox()) { + // Workaround for FF setting input prompt as the value if esc is + // pressed while the field is focused and empty (#8051). + addOnInputListener(getElement()); + // Workaround for FF updating component's internal value after + // having drag-and-dropped text from another element (#14056) + attachDropEventListener(getElement()); + } + } + + /** For internal use only. May be removed or replaced in the future. */ + public void setMaxLength(int newMaxLength) { + if (newMaxLength == maxLength) { + return; + } + maxLength = newMaxLength; + updateMaxLength(maxLength); + } + + /** + * This method is responsible for updating the DOM or otherwise ensuring + * that the given max length is enforced. Called when the max length for the + * field has changed. + * + * @param maxLength + * The new max length + */ + protected void updateMaxLength(int maxLength) { + if (maxLength >= 0) { + getElement().setPropertyInt("maxLength", maxLength); + } else { + getElement().removeAttribute("maxLength"); + + } + setMaxLengthToElement(maxLength); + } + + protected void setMaxLengthToElement(int newMaxLength) { + if (newMaxLength >= 0) { + getElement().setPropertyInt("maxLength", newMaxLength); + } else { + getElement().removeAttribute("maxLength"); + } + } + + public int getMaxLength() { + return maxLength; + } + + @Override + public void onChange(ChangeEvent event) { + valueChange(false); + } + + /** + * Called when the field value might have changed and/or the field was + * blurred. These are combined so the blur event is sent in the same batch + * as a possible value change event (these are often connected). + * + * @param blurred + * true if the field was blurred + */ + public void valueChange(boolean blurred) { + if (client != null && paintableId != null) { + boolean sendBlurEvent = false; + boolean sendValueChange = false; + + if (blurred && client.hasEventListeners(this, EventId.BLUR)) { + sendBlurEvent = true; + client.updateVariable(paintableId, EventId.BLUR, "", false); + } + + String newText = prompting ? "" : getText(); + if (newText != null && !newText.equals(valueBeforeEdit)) { + sendValueChange = immediate; + client.updateVariable(paintableId, "text", newText, false); + valueBeforeEdit = newText; + valueBeforeEditIsSynced = true; + } + + /* + * also send cursor position, no public api yet but for easier + * extension + */ + updateCursorPosition(); + + if (sendBlurEvent || sendValueChange) { + /* + * Avoid sending text change event as we will simulate it on the + * server side before value change events. + */ + textChangeEventTrigger.cancel(); + scheduled = false; + client.sendPendingVariableChanges(); + } + } + } + + /** + * Updates the cursor position variable if it has changed since the last + * update. + * + * @return true iff the value was updated + */ + protected boolean updateCursorPosition() { + if (WidgetUtil.isAttachedAndDisplayed(this)) { + int cursorPos = prompting ? 0 : getCursorPos(); + if (lastCursorPos != cursorPos) { + client.updateVariable(paintableId, + LegacyTextFieldConstants.VAR_CURSOR, cursorPos, false); + lastCursorPos = cursorPos; + return true; + } + } + return false; + } + + private static VTextField focusedTextField; + + public static void flushChangesFromFocusedTextField() { + if (focusedTextField != null) { + focusedTextField.onChange(null); + } + } + + @Override + public void onFocus(FocusEvent event) { + addStyleDependentName(CLASSNAME_FOCUS); + if (prompting) { + setText(""); + removeStyleDependentName(CLASSNAME_PROMPT); + setPrompting(false); + } + focusedTextField = this; + if (client != null && client.hasEventListeners(this, EventId.FOCUS)) { + client.updateVariable(paintableId, EventId.FOCUS, "", true); + } + } + + @Override + public void onBlur(BlurEvent event) { + // this is called twice on Chrome when e.g. changing tab while prompting + // field focused - do not change settings on the second time + if (focusedTextField != this) { + return; + } + removeStyleDependentName(CLASSNAME_FOCUS); + focusedTextField = null; + updateText(true); + } + + private void setPrompting(boolean prompting) { + this.prompting = prompting; + } + + public void setColumns(int columns) { + if (columns <= 0) { + return; + } + + setWidth(columns + "em"); + } + + @Override + public void onKeyDown(KeyDownEvent event) { + if (BrowserInfo.get().isIE() + && event.getNativeKeyCode() == KeyCodes.KEY_ENTER) { + // IE does not send change events when pressing enter in a text + // input so we handle it using a key listener instead + valueChange(false); + } else if (BrowserInfo.get().isFirefox() + && event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE + && getText().equals("")) { + // check after onInput event if inputPrompt has appeared as the + // value of the field + possibleInputError = true; + } + } + + public void setImmediate(boolean immediate) { + this.immediate = immediate; + } + + public void setInputPrompt(String inputPrompt) { + this.inputPrompt = inputPrompt; + } + + protected boolean isWordwrap() { + String wrap = getElement().getAttribute("wrap"); + return !"off".equals(wrap); + } + + private native void addOnInputListener(Element el) + /*-{ + var self = this; + el.oninput = $entry(function() { + self.@com.vaadin.v7.client.ui.VTextField::checkForInputError()(); + }); + }-*/; + + private native void removeOnInputListener(Element el) + /*-{ + el.oninput = null; + }-*/; + + private void checkForInputError() { + if (possibleInputError && getText().equals(inputPrompt)) { + setText(""); + } + possibleInputError = false; + } +} diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/optiongroup/OptionGroupBaseConnector.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/optiongroup/OptionGroupBaseConnector.java index 483abbc32b..fdeb2e08dd 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/optiongroup/OptionGroupBaseConnector.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/optiongroup/OptionGroupBaseConnector.java @@ -21,10 +21,10 @@ import com.vaadin.client.Paintable; import com.vaadin.client.StyleConstants; import com.vaadin.client.UIDL; import com.vaadin.client.ui.VNativeButton; -import com.vaadin.client.v7.ui.VLegacyTextField; import com.vaadin.shared.ui.select.AbstractSelectState; import com.vaadin.v7.client.ui.AbstractFieldConnector; import com.vaadin.v7.client.ui.VOptionGroupBase; +import com.vaadin.v7.client.ui.VTextField; public abstract class OptionGroupBaseConnector extends AbstractFieldConnector implements Paintable { @@ -65,7 +65,7 @@ public abstract class OptionGroupBaseConnector extends AbstractFieldConnector getWidget().newItemButton.addClickHandler(getWidget()); getWidget().newItemButton .addStyleName(StyleConstants.UI_WIDGET); - getWidget().newItemField = new VLegacyTextField(); + getWidget().newItemField = new VTextField(); getWidget().newItemField.client = getConnection(); getWidget().newItemField.paintableId = getConnectorId(); getWidget().newItemField.addKeyPressHandler(getWidget()); diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/passwordfield/PasswordFieldConnector.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/passwordfield/PasswordFieldConnector.java index 033e879ff2..295eda7fa6 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/passwordfield/PasswordFieldConnector.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/passwordfield/PasswordFieldConnector.java @@ -16,17 +16,17 @@ package com.vaadin.v7.client.ui.passwordfield; -import com.vaadin.client.v7.ui.VLegacyPasswordField; -import com.vaadin.client.v7.ui.textfield.LegacyTextFieldConnector; import com.vaadin.shared.ui.Connect; +import com.vaadin.v7.client.ui.VPasswordField; +import com.vaadin.v7.client.ui.textfield.TextFieldConnector; import com.vaadin.v7.ui.PasswordField; @Deprecated @Connect(PasswordField.class) -public class PasswordFieldConnector extends LegacyTextFieldConnector { +public class PasswordFieldConnector extends TextFieldConnector { @Override - public VLegacyPasswordField getWidget() { - return (VLegacyPasswordField) super.getWidget(); + public VPasswordField getWidget() { + return (VPasswordField) super.getWidget(); } } diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/textarea/TextAreaConnector.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/textarea/TextAreaConnector.java index 61d86dee14..d183ec39c0 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/textarea/TextAreaConnector.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/textarea/TextAreaConnector.java @@ -20,14 +20,14 @@ import com.google.gwt.dom.client.Element; import com.google.gwt.event.dom.client.MouseUpEvent; import com.google.gwt.event.dom.client.MouseUpHandler; import com.vaadin.client.WidgetUtil.CssSize; -import com.vaadin.client.v7.ui.textfield.LegacyTextFieldConnector; import com.vaadin.shared.ui.Connect; import com.vaadin.v7.client.ui.VTextArea; +import com.vaadin.v7.client.ui.textfield.TextFieldConnector; import com.vaadin.v7.shared.ui.textarea.TextAreaState; import com.vaadin.v7.ui.TextArea; @Connect(TextArea.class) -public class TextAreaConnector extends LegacyTextFieldConnector { +public class TextAreaConnector extends TextFieldConnector { @Override public TextAreaState getState() { diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/textfield/TextFieldConnector.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/textfield/TextFieldConnector.java new file mode 100644 index 0000000000..34f6c7068a --- /dev/null +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/textfield/TextFieldConnector.java @@ -0,0 +1,124 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed 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 com.vaadin.v7.client.ui.textfield; + +import com.google.gwt.core.client.Scheduler; +import com.google.gwt.user.client.Command; +import com.vaadin.client.ApplicationConnection; +import com.vaadin.client.Paintable; +import com.vaadin.client.UIDL; +import com.vaadin.client.Util; +import com.vaadin.client.ui.AbstractFieldConnector; +import com.vaadin.shared.ui.Connect; +import com.vaadin.shared.ui.Connect.LoadStyle; +import com.vaadin.shared.v7.ui.textfield.LegacyAbstractTextFieldState; +import com.vaadin.shared.v7.ui.textfield.LegacyTextFieldConstants; +import com.vaadin.v7.client.ui.VTextField; +import com.vaadin.v7.ui.TextField; + +@Deprecated +@Connect(value = TextField.class, loadStyle = LoadStyle.EAGER) +public class TextFieldConnector extends AbstractFieldConnector + implements Paintable { + + @Override + public LegacyAbstractTextFieldState getState() { + return (LegacyAbstractTextFieldState) super.getState(); + } + + @Override + public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { + // Save details + getWidget().client = client; + getWidget().paintableId = uidl.getId(); + + if (!isRealUpdate(uidl)) { + return; + } + + getWidget().setReadOnly(isReadOnly()); + + getWidget().setInputPrompt(getState().inputPrompt); + getWidget().setMaxLength(getState().maxLength); + getWidget().setImmediate(getState().immediate); + + getWidget().listenTextChangeEvents = hasEventListener("ie"); + if (getWidget().listenTextChangeEvents) { + getWidget().textChangeEventMode = uidl.getStringAttribute( + LegacyTextFieldConstants.ATTR_TEXTCHANGE_EVENTMODE); + if (getWidget().textChangeEventMode + .equals(LegacyTextFieldConstants.TEXTCHANGE_MODE_EAGER)) { + getWidget().textChangeEventTimeout = 1; + } else { + getWidget().textChangeEventTimeout = uidl.getIntAttribute( + LegacyTextFieldConstants.ATTR_TEXTCHANGE_TIMEOUT); + if (getWidget().textChangeEventTimeout < 1) { + // Sanitize and allow lazy/timeout with timeout set to 0 to + // work as eager + getWidget().textChangeEventTimeout = 1; + } + } + getWidget().sinkEvents(VTextField.TEXTCHANGE_EVENTS); + getWidget().attachCutEventListener(getWidget().getElement()); + } + getWidget().setColumns(getState().columns); + + String text = getState().text; + if (text == null) { + text = ""; + } + /* + * We skip the text content update if field has been repainted, but text + * has not been changed (#6588). Additional sanity check verifies there + * is no change in the queue (in which case we count more on the server + * side value). is updated only when it looses focus, so we + * force updating if not focused. Lost focus issue appeared in (#15144) + */ + if (!(Util.getFocusedElement() == getWidget().getElement()) + || !uidl.getBooleanAttribute( + LegacyTextFieldConstants.ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS) + || getWidget().valueBeforeEdit == null + || !text.equals(getWidget().valueBeforeEdit)) { + getWidget().updateFieldContent(text); + } + + if (uidl.hasAttribute("selpos")) { + final int pos = uidl.getIntAttribute("selpos"); + final int length = uidl.getIntAttribute("sellen"); + /* + * Gecko defers setting the text so we need to defer the selection. + */ + Scheduler.get().scheduleDeferred(new Command() { + @Override + public void execute() { + getWidget().setSelectionRange(pos, length); + } + }); + } + } + + @Override + public VTextField getWidget() { + return (VTextField) super.getWidget(); + } + + @Override + public void flush() { + getWidget().valueChange(false); + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/event/FieldEvents.java b/compatibility-server/src/main/java/com/vaadin/v7/event/FieldEvents.java new file mode 100644 index 0000000000..abd17df49b --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/event/FieldEvents.java @@ -0,0 +1,109 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed 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 com.vaadin.v7.event; + +import java.io.Serializable; +import java.lang.reflect.Method; + +import com.vaadin.event.ConnectorEventListener; +import com.vaadin.ui.Component; +import com.vaadin.util.ReflectTools; +import com.vaadin.v7.ui.Field; +import com.vaadin.v7.ui.Field.ValueChangeEvent; +import com.vaadin.v7.ui.TextField; + +/** + * Interface that serves as a wrapper for {@link Field} related events. + */ +public interface FieldEvents { + + /** + * TextChangeEvents are fired when the user is editing the text content of a + * field. Most commonly text change events are triggered by typing text with + * keyboard, but e.g. pasting content from clip board to a text field also + * triggers an event. + *

+ * TextChangeEvents differ from {@link ValueChangeEvent}s so that they are + * triggered repeatedly while the end user is filling the field. + * ValueChangeEvents are not fired until the user for example hits enter or + * focuses another field. Also note the difference that TextChangeEvents are + * only fired if the change is triggered from the user, while + * ValueChangeEvents are also fired if the field value is set by the + * application code. + *

+ * The {@link TextChangeNotifier}s implementation may decide when exactly + * TextChangeEvents are fired. TextChangeEvents are not necessary fire for + * example on each key press, but buffered with a small delay. The + * {@code TextField} component supports different modes for triggering + * TextChangeEvents. + * + * @see TextChangeListener + * @see TextChangeNotifier + * @see TextField#setTextChangeEventMode(com.vaadin.ui.TextField.TextChangeEventMode) + * @since 6.5 + */ + public static abstract class TextChangeEvent extends Component.Event { + + public TextChangeEvent(Component source) { + super(source); + } + + /** + * @return the text content of the field after the + * {@link TextChangeEvent} + */ + public abstract String getText(); + + /** + * @return the cursor position during after the {@link TextChangeEvent} + */ + public abstract int getCursorPosition(); + } + + /** + * A listener for {@link TextChangeEvent}s. + * + * @since 6.5 + */ + public interface TextChangeListener extends ConnectorEventListener { + + public static String EVENT_ID = "ie"; + public static Method EVENT_METHOD = ReflectTools.findMethod( + TextChangeListener.class, "textChange", TextChangeEvent.class); + + /** + * This method is called repeatedly while the text is edited by a user. + * + * @param event + * the event providing details of the text change + */ + public void textChange(TextChangeEvent event); + } + + /** + * An interface implemented by a {@link Field} supporting + * {@link TextChangeEvent}s. An example a {@link TextField} supports + * {@link TextChangeListener}s. + */ + public interface TextChangeNotifier extends Serializable { + public void addTextChangeListener(TextChangeListener listener); + + public void removeTextChangeListener(TextChangeListener listener); + + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/ui/AbstractTextField.java b/compatibility-server/src/main/java/com/vaadin/v7/ui/AbstractTextField.java new file mode 100644 index 0000000000..f534662583 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/ui/AbstractTextField.java @@ -0,0 +1,813 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed 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 com.vaadin.v7.ui; + +import java.util.Collection; +import java.util.Map; + +import org.jsoup.nodes.Attributes; +import org.jsoup.nodes.Element; + +import com.vaadin.event.FieldEvents.BlurEvent; +import com.vaadin.event.FieldEvents.BlurListener; +import com.vaadin.event.FieldEvents.BlurNotifier; +import com.vaadin.event.FieldEvents.FocusEvent; +import com.vaadin.event.FieldEvents.FocusListener; +import com.vaadin.event.FieldEvents.FocusNotifier; +import com.vaadin.server.PaintException; +import com.vaadin.server.PaintTarget; +import com.vaadin.shared.v7.ui.textfield.LegacyAbstractTextFieldState; +import com.vaadin.shared.v7.ui.textfield.LegacyTextFieldConstants; +import com.vaadin.ui.LegacyComponent; +import com.vaadin.ui.declarative.DesignAttributeHandler; +import com.vaadin.ui.declarative.DesignContext; +import com.vaadin.v7.event.FieldEvents.TextChangeEvent; +import com.vaadin.v7.event.FieldEvents.TextChangeListener; +import com.vaadin.v7.event.FieldEvents.TextChangeNotifier; + +@Deprecated +public abstract class AbstractTextField extends AbstractField implements + BlurNotifier, FocusNotifier, TextChangeNotifier, LegacyComponent { + + /** + * Null representation. + */ + private String nullRepresentation = "null"; + /** + * Is setting to null from non-null value allowed by setting with null + * representation . + */ + private boolean nullSettingAllowed = false; + /** + * The text content when the last messages to the server was sent. Cleared + * when value is changed. + */ + private String lastKnownTextContent; + + /** + * The position of the cursor when the last message to the server was sent. + */ + private int lastKnownCursorPosition; + + /** + * Flag indicating that a text change event is pending to be triggered. + * Cleared by {@link #setInternalValue(Object)} and when the event is fired. + */ + private boolean textChangeEventPending; + + private boolean isFiringTextChangeEvent = false; + + private TextChangeEventMode textChangeEventMode = TextChangeEventMode.LAZY; + + private final int DEFAULT_TEXTCHANGE_TIMEOUT = 400; + + private int textChangeEventTimeout = DEFAULT_TEXTCHANGE_TIMEOUT; + + /** + * Temporarily holds the new selection position. Cleared on paint. + */ + private int selectionPosition = -1; + + /** + * Temporarily holds the new selection length. + */ + private int selectionLength; + + /** + * Flag used to determine whether we are currently handling a state change + * triggered by a user. Used to properly fire text change event before value + * change event triggered by the client side. + */ + private boolean changingVariables; + + protected AbstractTextField() { + super(); + } + + @Override + protected LegacyAbstractTextFieldState getState() { + return (LegacyAbstractTextFieldState) super.getState(); + } + + @Override + protected LegacyAbstractTextFieldState getState(boolean markAsDirty) { + return (LegacyAbstractTextFieldState) super.getState(markAsDirty); + } + + @Override + public void beforeClientResponse(boolean initial) { + super.beforeClientResponse(initial); + + String value = getValue(); + if (value == null) { + value = getNullRepresentation(); + } + getState().text = value; + } + + @Override + public void paintContent(PaintTarget target) throws PaintException { + + if (selectionPosition != -1) { + target.addAttribute("selpos", selectionPosition); + target.addAttribute("sellen", selectionLength); + selectionPosition = -1; + } + + if (hasListeners(TextChangeEvent.class)) { + target.addAttribute( + LegacyTextFieldConstants.ATTR_TEXTCHANGE_EVENTMODE, + getTextChangeEventMode().toString()); + target.addAttribute( + LegacyTextFieldConstants.ATTR_TEXTCHANGE_TIMEOUT, + getTextChangeTimeout()); + if (lastKnownTextContent != null) { + /* + * The field has be repainted for some reason (e.g. caption, + * size, stylename), but the value has not been changed since + * the last text change event. Let the client side know about + * the value the server side knows. Client side may then ignore + * the actual value, depending on its state. + */ + target.addAttribute( + LegacyTextFieldConstants.ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS, + true); + } + } + + } + + @Override + public void changeVariables(Object source, Map variables) { + changingVariables = true; + + try { + + // Sets the height set by the user when resize the