Browse Source

Merge remote-tracking branch 'origin/7.0'

Change-Id: Id48ccb3c400a78cddb8bb5c7bbcf2d65174e59d0
tags/7.1.0.beta1
Artur Signell 11 years ago
parent
commit
fbdc52551e
63 changed files with 2923 additions and 2281 deletions
  1. 82
    941
      WebContent/release-notes.html
  2. 6
    0
      all/build.xml
  3. 0
    16
      build/bin/closed-to-rn.py
  4. 7
    0
      buildhelpers/build.xml
  5. 3
    1
      buildhelpers/ivy.xml
  6. 46
    0
      buildhelpers/src/com/vaadin/buildhelpers/FetchReleaseNotesTickets.java
  7. 3
    0
      client-compiled/build.xml
  8. 16
    0
      client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java
  9. 35
    0
      client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java
  10. 19
    0
      client-compiler/src/com/vaadin/server/widgetsetutils/metadata/WidgetInitVisitor.java
  11. 6
    0
      client/src/com/vaadin/client/ApplicationConfiguration.java
  12. 45
    10
      client/src/com/vaadin/client/ApplicationConnection.java
  13. 2
    1
      client/src/com/vaadin/client/ConnectorMap.java
  14. 1
    1
      client/src/com/vaadin/client/FastStringMap.java
  15. 1
    1
      client/src/com/vaadin/client/JsArrayObject.java
  16. 24
    0
      client/src/com/vaadin/client/VCaption.java
  17. 2
    0
      client/src/com/vaadin/client/VTooltip.java
  18. 4
    0
      client/src/com/vaadin/client/metadata/AsyncBundleLoader.java
  19. 19
    0
      client/src/com/vaadin/client/metadata/TypeDataStore.java
  20. 76
    17
      client/src/com/vaadin/client/ui/AbstractComponentConnector.java
  21. 4
    0
      client/src/com/vaadin/client/ui/AbstractConnector.java
  22. 7
    4
      client/src/com/vaadin/client/ui/VAbsoluteLayout.java
  23. 4
    0
      client/src/com/vaadin/client/ui/VCssLayout.java
  24. 432
    76
      client/src/com/vaadin/client/ui/VScrollTable.java
  25. 6
    9
      client/src/com/vaadin/client/ui/VTextField.java
  26. 32
    6
      client/src/com/vaadin/client/ui/VTreeTable.java
  27. 3
    0
      client/src/com/vaadin/client/ui/VUI.java
  28. 6
    0
      client/src/com/vaadin/client/ui/label/LabelConnector.java
  29. 5
    1
      client/src/com/vaadin/client/ui/link/LinkConnector.java
  30. 1
    0
      client/src/com/vaadin/client/ui/table/TableConnector.java
  31. 8
    0
      client/src/com/vaadin/client/ui/tabsheet/TabsheetBaseConnector.java
  32. 4
    2
      client/src/com/vaadin/client/ui/textfield/TextFieldConnector.java
  33. 18
    1
      client/src/com/vaadin/client/ui/ui/UIConnector.java
  34. 29
    6
      common.xml
  35. 7
    0
      server/src/com/vaadin/ui/CheckBox.java
  36. 15
    0
      server/src/com/vaadin/ui/ProgressIndicator.java
  37. 16
    0
      server/src/com/vaadin/ui/Slider.java
  38. 27
    0
      server/src/com/vaadin/ui/Tree.java
  39. 62
    0
      server/tests/src/com/vaadin/tests/server/component/tree/TreeTest.java
  40. 1121
    1144
      theme-compiler/src/com/vaadin/sass/internal/parser/Parser.java
  41. 31
    20
      theme-compiler/src/com/vaadin/sass/internal/parser/Parser.jj
  42. 15
    15
      theme-compiler/src/com/vaadin/sass/internal/parser/ParserTokenManager.java
  43. 26
    5
      theme-compiler/src/com/vaadin/sass/internal/visitor/MixinNodeHandler.java
  44. 9
    0
      theme-compiler/tests/resources/automatic/css/nested-selector-begin-with-plus.css
  45. 9
    0
      theme-compiler/tests/resources/automatic/scss/nested-selector-begin-with-plus.scss
  46. 0
    0
      theme-compiler/tests/resources/sasslang/css/95-test_nested_selector_with_child_selector_hack_extender_and_sibling_selector_extendee.css
  47. 0
    0
      theme-compiler/tests/resources/sasslang/scss/95-test_nested_selector_with_child_selector_hack_extender_and_sibling_selector_extendee.scss
  48. 4
    0
      theme-compiler/tests/resources/scss/mixin-extra-params.scss
  49. 25
    0
      theme-compiler/tests/src/com/vaadin/sass/testcases/scss/MixinExtraParameters.java
  50. 4
    0
      uitest/build.xml
  51. 37
    0
      uitest/src/com/vaadin/tests/components/absolutelayout/AbsoluteLayoutResizing.html
  52. 44
    0
      uitest/src/com/vaadin/tests/components/absolutelayout/AbsoluteLayoutResizing.java
  53. 32
    0
      uitest/src/com/vaadin/tests/components/slider/SliderValueFromDataSource.html
  54. 59
    0
      uitest/src/com/vaadin/tests/components/slider/SliderValueFromDataSource.java
  55. 51
    0
      uitest/src/com/vaadin/tests/components/textfield/TextFieldMaxLengthRemovedFromDOM.html
  56. 37
    0
      uitest/src/com/vaadin/tests/components/textfield/TextFieldMaxLengthRemovedFromDOM.java
  57. 31
    0
      uitest/src/com/vaadin/tests/components/textfield/TextFieldWithDataSourceAndInputPrompt.html
  58. 63
    0
      uitest/src/com/vaadin/tests/components/textfield/TextFieldWithDataSourceAndInputPrompt.java
  59. 69
    0
      uitest/src/com/vaadin/tests/components/treetable/TreeTableExtraScrollBarWithChildren.html
  60. 92
    0
      uitest/src/com/vaadin/tests/components/treetable/TreeTableExtraScrollbarWithChildren.java
  61. 37
    0
      uitest/src/com/vaadin/tests/debug/HierarchyAfterAnalyzeLayouts.html
  62. 40
    0
      uitest/src/com/vaadin/tests/debug/HierarchyAfterAnalyzeLayouts.java
  63. 4
    4
      uitest/src/com/vaadin/tests/minitutorials/v7a1/CreatingPreserveState.java

+ 82
- 941
WebContent/release-notes.html
File diff suppressed because it is too large
View File


+ 6
- 0
all/build.xml View File

@@ -35,6 +35,9 @@
</target>

<target name="javadoc" depends="copy-jars">
<!-- Ensure filtered webcontent files are available -->
<antcall target="common.filter.webcontent" />

<!-- Unpack all source files to javadoc.temp.dir-->
<antcontrib:foreach list="${modules.to.publish.to.maven}" target="unzip.to.javadoctemp" param="module" />

@@ -76,6 +79,9 @@

</target>
<target name="zip" depends="copy-jars, javadoc">
<!-- Ensure filtered webcontent files are available -->
<antcall target="common.filter.webcontent" />

<zip destfile="${zip.file}">
<fileset dir="${temp.dir}">
<!-- Avoid conflicts with servlet and portlet API. They are provided by the container -->

+ 0
- 16
build/bin/closed-to-rn.py View File

@@ -1,16 +0,0 @@
#!/usr/bin/python

import sys,string

filename = sys.argv[1]

fin = open(filename, "r")
lines = fin.readlines()
fin.close()

for line in lines:
fields = string.split(line, "\t")

if fields[0] != "id":
ticketid = "<a href=\"http://dev.vaadin.com/ticket/%s\">#%s</a>" % (fields[0],fields[0])
print " <li>%s: %s</li>" % (ticketid, fields[1])

+ 7
- 0
buildhelpers/build.xml View File

@@ -36,6 +36,13 @@
</antcall>
</target>

<target name="fetch-release-notes-tickets">
<antcall target="common.exec-buildhelper">
<param name="main.class" value="com.vaadin.buildhelpers.FetchReleaseNotesTickets" />
<param name="output" value="${output}" />
</antcall>
</target>

<target name="tests" depends="checkstyle">
<!--<antcall target="common.tests.run" />-->
<echo>WHAT? No JUnit tests for ${module.name}!</echo>

+ 3
- 1
buildhelpers/ivy.xml View File

@@ -27,6 +27,8 @@
<artifact type="pom" ext="pom" />

</publications>
<dependencies />
<dependencies>
<dependency org="commons-io" name="commons-io" rev="1.4" />
</dependencies>

</ivy-module>

+ 46
- 0
buildhelpers/src/com/vaadin/buildhelpers/FetchReleaseNotesTickets.java View File

@@ -0,0 +1,46 @@
package com.vaadin.buildhelpers;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;

import org.apache.commons.io.IOUtils;

public class FetchReleaseNotesTickets {
private static final String queryURL = "http://dev.vaadin.com/query?status=closed&amp;milestone=Vaadin+@version@&amp;resolution=fixed&amp;format=tab&amp;order=id";
private static final String ticketTemplate = " <li><a href=\"http://dev.vaadin.com/ticket/@ticket@\">#@ticket@</a>: @description@</li>";

public static void main(String[] args) throws IOException {
String version = System.getProperty("vaadin.version");
if (version == null || version.equals("")) {
usage();
}

URL url = new URL(queryURL.replace("@version@", version));
URLConnection connection = url.openConnection();
InputStream urlStream = connection.getInputStream();

@SuppressWarnings("unchecked")
List<String> tickets = IOUtils.readLines(urlStream);

for (String ticket : tickets) {
String[] fields = ticket.split("\t");
if ("id".equals(fields[0])) {
// This is the header
continue;
}
System.out.println(ticketTemplate.replace("@ticket@", fields[0])
.replace("@description@", fields[1]));
}
urlStream.close();
}

private static void usage() {
System.err.println("Usage: "
+ FetchReleaseNotesTickets.class.getSimpleName()
+ " -Dvaadin.version=<version>");
System.exit(1);
}
}

+ 3
- 0
client-compiled/build.xml View File

@@ -98,6 +98,9 @@
</target>

<target name="client-compiled-cache.jar" depends="default-widgetset-cache">
<!-- Ensure filtered webcontent files are available -->
<antcall target="common.filter.webcontent" />

<jar file="${compiled-cache.jar}" compress="true">
<fileset dir="${gwtar.dir}">
<include name="**/*.gwtar" />

+ 16
- 0
client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java View File

@@ -334,6 +334,22 @@ public class ConnectorBundleLoaderFactory extends Generator {
writeGetters(logger, w, bundle);
writeSerializers(logger, w, bundle);
writeDelegateToWidget(logger, w, bundle);
writeHasGetTooltip(logger, w, bundle);
}

/**
* @deprecated As of 7.0.1. This is just a hack to avoid breaking backwards
* compatibility and will be removed in Vaadin 7.1
*/
@Deprecated
private void writeHasGetTooltip(TreeLogger logger, SplittingSourceWriter w,
ConnectorBundle bundle) {
Set<JClassType> types = bundle.getHasGetTooltip();
for (JClassType type : types) {
w.println("store.setHasGetTooltipInfo(%s);",
getClassLiteralString(type));
w.splitIfNeeded();
}
}

private void writeDelegateToWidget(TreeLogger logger,

+ 35
- 0
client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java View File

@@ -63,6 +63,7 @@ public class ConnectorBundle {
private final Set<JClassType> needsGwtConstructor = new HashSet<JClassType>();
private final Set<JClassType> visitedTypes = new HashSet<JClassType>();
private final Set<JClassType> needsProxySupport = new HashSet<JClassType>();
private final Set<JClassType> hasGetTooltip = new HashSet<JClassType>();

private final Map<JClassType, Set<String>> identifiers = new HashMap<JClassType, Set<String>>();
private final Map<JClassType, Set<JMethod>> needsReturnType = new HashMap<JClassType, Set<JMethod>>();
@@ -618,4 +619,38 @@ public class ConnectorBundle {
public Set<Property> getNeedsDelegateToWidget() {
return Collections.unmodifiableSet(needsDelegateToWidget);
}

/**
* @deprecated As of 7.0.1. This is just a hack to avoid breaking backwards
* compatibility and will be removed in Vaadin 7.1
*/
@Deprecated
public Set<JClassType> getHasGetTooltip() {
return Collections.unmodifiableSet(hasGetTooltip);
}

/**
* @deprecated As of 7.0.1. This is just a hack to avoid breaking backwards
* compatibility and will be removed in Vaadin 7.1
*/
@Deprecated
public void setHasGetTooltip(JClassType type) {
if (!isHasGetTooltip(type)) {
hasGetTooltip.add(type);
}
}

/**
* @deprecated As of 7.0.1. This is just a hack to avoid breaking backwards
* compatibility and will be removed in Vaadin 7.1
*/
@Deprecated
private boolean isHasGetTooltip(JClassType type) {
if (hasGetTooltip.contains(type)) {
return true;
} else {
return previousBundle != null
&& previousBundle.isHasGetTooltip(type);
}
}
}

+ 19
- 0
client-compiler/src/com/vaadin/server/widgetsetutils/metadata/WidgetInitVisitor.java View File

@@ -47,6 +47,25 @@ public class WidgetInitVisitor extends TypeVisitor {
bundle.setNeedsReturnType(type, getWidget);
}

// Hack to detect when getTooltipInfo has a custom implementation
// #11051
JClassType getTooltipParamType = type.getOracle().findType(
"com.google.gwt.dom.client.Element");
JMethod getTooltipInfoMethod = findInheritedMethod(type,
"getTooltipInfo", getTooltipParamType);
if (getTooltipInfoMethod == null) {
logger.log(Type.ERROR, "Could not find getTooltipInfo in "
+ type.getQualifiedSourceName());
throw new UnableToCompleteException();
}
JClassType enclosingType = getTooltipInfoMethod.getEnclosingType();
if (!enclosingType.getQualifiedSourceName().equals(
AbstractComponentConnector.class.getCanonicalName())) {
logger.log(Type.WARN, type.getQualifiedSourceName()
+ " has overridden getTooltipInfo");
bundle.setHasGetTooltip(type);
}

// Check state properties for @DelegateToWidget
JMethod getState = findInheritedMethod(type, "getState");
JClassType stateType = getState.getReturnType().isClass();

+ 6
- 0
client/src/com/vaadin/client/ApplicationConfiguration.java View File

@@ -381,11 +381,14 @@ public class ApplicationConfiguration implements EntryPoint {

@Override
public void execute() {
Profiler.enter("ApplicationConfiguration.startApplication");
ApplicationConfiguration appConf = getConfigFromDOM(applicationId);
ApplicationConnection a = GWT
.create(ApplicationConnection.class);
a.init(widgetSet, appConf);
runningApplications.add(a);
Profiler.leave("ApplicationConfiguration.startApplication");

a.start();
}
});
@@ -532,6 +535,8 @@ public class ApplicationConfiguration implements EntryPoint {

@Override
public void onModuleLoad() {
Profiler.reset();
Profiler.enter("ApplicationConfiguration.onModuleLoad");

BrowserInfo browserInfo = BrowserInfo.get();

@@ -567,6 +572,7 @@ public class ApplicationConfiguration implements EntryPoint {
VConsole.getImplementation().error(e);
}
});
Profiler.leave("ApplicationConfiguration.onModuleLoad");

if (SuperDevMode.enableBasedOnParameter()) {
// Do not start any application as super dev mode will refresh the

+ 45
- 10
client/src/com/vaadin/client/ApplicationConnection.java View File

@@ -1311,8 +1311,6 @@ public class ApplicationConnection {
return;
}

Profiler.reset();

VConsole.log("Handling message from server");
eventBus.fireEvent(new ResponseHandlingStartedEvent(this));

@@ -1397,15 +1395,12 @@ public class ApplicationConnection {
Profiler.leave("Handling locales");

Profiler.enter("Handling meta information");
boolean repaintAll = false;
ValueMap meta = null;
if (json.containsKey("meta")) {
VConsole.log(" * Handling meta information");
meta = json.getValueMap("meta");
if (meta.containsKey("repaintAll")) {
repaintAll = true;
uIConnector.getWidget().clear();
getConnectorMap().clear();
prepareRepaintAll();
if (meta.containsKey("invalidLayouts")) {
validatingLayouts = true;
}
@@ -1528,10 +1523,46 @@ public class ApplicationConnection {
endRequest();

if (Profiler.isEnabled()) {
Profiler.logTimings();
Profiler.reset();
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
Profiler.logTimings();
Profiler.reset();
}
});
}

}

/**
* Properly clean up any old stuff to ensure everything is properly
* reinitialized.
*/
private void prepareRepaintAll() {
String uiConnectorId = uIConnector.getConnectorId();
if (uiConnectorId == null) {
// Nothing to clear yet
return;
}

// Create fake server response that says that the uiConnector
// has no children
JSONObject fakeHierarchy = new JSONObject();
fakeHierarchy.put(uiConnectorId, new JSONArray());
JSONObject fakeJson = new JSONObject();
fakeJson.put("hierarchy", fakeHierarchy);
ValueMap fakeValueMap = fakeJson.getJavaScriptObject().cast();

// Update hierarchy based on the fake response
ConnectorHierarchyUpdateResult connectorHierarchyUpdateResult = updateConnectorHierarchy(fakeValueMap);

// Send hierarchy events based on the fake update
sendHierarchyChangeEvents(connectorHierarchyUpdateResult.events);

// Unregister all the old connectors that have now been removed
unregisterRemovedConnectors();

getLayoutManager().cleanMeasuredSizes();
}

private void updateCaptions(
@@ -1548,8 +1579,10 @@ public class ApplicationConnection {

// Find components with potentially changed caption state
for (StateChangeEvent event : pendingStateChangeEvents) {
ServerConnector connector = event.getConnector();
needsCaptionUpdate.add(connector);
if (VCaption.mightChange(event)) {
ServerConnector connector = event.getConnector();
needsCaptionUpdate.add(connector);
}
}

// Update captions for all suitable candidates
@@ -1916,6 +1949,7 @@ public class ApplicationConnection {
}
}

Profiler.enter("updateConnectorState newWithoutState");
// Fire events for properties using the default value for newly
// created connectors even if there were no state changes
for (ServerConnector connector : remainingNewConnectors) {
@@ -1928,6 +1962,7 @@ public class ApplicationConnection {
events.add(event);

}
Profiler.leave("updateConnectorState newWithoutState");

Profiler.leave("updateConnectorState");


+ 2
- 1
client/src/com/vaadin/client/ConnectorMap.java View File

@@ -126,8 +126,9 @@ public class ConnectorMap {
componentDetail.setConnector(connector);
if (connector instanceof ComponentConnector) {
ComponentConnector pw = (ComponentConnector) connector;
Widget widget = pw.getWidget();
Profiler.enter("ConnectorMap.setConnectorId");
setConnectorId(pw.getWidget().getElement(), id);
setConnectorId(widget.getElement(), id);
Profiler.leave("ConnectorMap.setConnectorId");
}
Profiler.leave("ConnectorMap.registerConnector");

+ 1
- 1
client/src/com/vaadin/client/FastStringMap.java View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012 Vaadin Ltd.
* Copyright 2000-2013 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

+ 1
- 1
client/src/com/vaadin/client/JsArrayObject.java View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012 Vaadin Ltd.
* Copyright 2000-2013 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

+ 24
- 0
client/src/com/vaadin/client/VCaption.java View File

@@ -20,6 +20,7 @@ import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.HTML;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.ui.AbstractFieldConnector;
import com.vaadin.client.ui.Icon;
import com.vaadin.shared.AbstractComponentState;
@@ -407,6 +408,29 @@ public class VCaption extends HTML {
return false;
}

/**
* Checks whether anything in a given state change might cause the caption
* to change.
*
* @param event
* the state change event to check
* @return <code>true</code> if the caption might have changed; otherwise
* <code>false</code>
*/
public static boolean mightChange(StateChangeEvent event) {
if (event.hasPropertyChanged("caption")) {
return true;
}
if (event.hasPropertyChanged("resources")) {
return true;
}
if (event.hasPropertyChanged("errorMessage")) {
return true;
}

return false;
}

/**
* Returns Paintable for which this Caption belongs to.
*

+ 2
- 0
client/src/com/vaadin/client/VTooltip.java View File

@@ -366,8 +366,10 @@ public class VTooltip extends VOverlay {
* Widget which DOM handlers are connected
*/
public void connectHandlersToWidget(Widget widget) {
Profiler.enter("VTooltip.connectHandlersToWidget");
widget.addDomHandler(tooltipEventHandler, MouseMoveEvent.getType());
widget.addDomHandler(tooltipEventHandler, ClickEvent.getType());
widget.addDomHandler(tooltipEventHandler, KeyDownEvent.getType());
Profiler.leave("VTooltip.connectHandlersToWidget");
}
}

+ 4
- 0
client/src/com/vaadin/client/metadata/AsyncBundleLoader.java View File

@@ -19,6 +19,8 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.vaadin.client.Profiler;

public abstract class AsyncBundleLoader {
public enum State {
NOT_STARTED, LOADING, LOADED, ERROR;
@@ -63,9 +65,11 @@ public abstract class AsyncBundleLoader {

public void load(BundleLoadCallback callback, TypeDataStore store) {
assert state == State.NOT_STARTED;
Profiler.enter("AsyncBundleLoader.load");
state = State.LOADING;
addCallback(callback);
load(store);
Profiler.leave("AsyncBundleLoader.load");
}

public void addCallback(BundleLoadCallback callback) {

+ 19
- 0
client/src/com/vaadin/client/metadata/TypeDataStore.java View File

@@ -38,6 +38,7 @@ public class TypeDataStore {

private final FastStringSet delayedMethods = FastStringSet.create();
private final FastStringSet lastOnlyMethods = FastStringSet.create();
private final FastStringSet hasGetTooltipInfo = FastStringSet.create();

private final FastStringMap<Type> returnTypes = FastStringMap.create();
private final FastStringMap<Invoker> invokers = FastStringMap.create();
@@ -276,4 +277,22 @@ public class TypeDataStore {
public static boolean hasProperties(Type type) {
return get().properties.containsKey(type.getSignature());
}

/**
* @deprecated As of 7.0.1. This is just a hack to avoid breaking backwards
* compatibility and will be removed in Vaadin 7.1
*/
@Deprecated
public void setHasGetTooltipInfo(Class<?> clazz) {
hasGetTooltipInfo.add(getType(clazz).getSignature());
}

/**
* @deprecated As of 7.0.1. This is just a hack to avoid breaking backwards
* compatibility and will be removed in Vaadin 7.1
*/
@Deprecated
public static boolean getHasGetTooltipInfo(Class clazz) {
return get().hasGetTooltipInfo.contains(getType(clazz).getSignature());
}
}

+ 76
- 17
client/src/com/vaadin/client/ui/AbstractComponentConnector.java View File

@@ -15,9 +15,6 @@
*/
package com.vaadin.client.ui;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.ui.Focusable;
@@ -27,6 +24,7 @@ import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.ComponentConnector;
import com.vaadin.client.HasComponentsConnector;
import com.vaadin.client.LayoutManager;
import com.vaadin.client.Profiler;
import com.vaadin.client.ServerConnector;
import com.vaadin.client.StyleConstants;
import com.vaadin.client.TooltipInfo;
@@ -37,6 +35,7 @@ import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.metadata.NoDataException;
import com.vaadin.client.metadata.Type;
import com.vaadin.client.metadata.TypeData;
import com.vaadin.client.metadata.TypeDataStore;
import com.vaadin.client.ui.datefield.PopupDateFieldConnector;
import com.vaadin.client.ui.ui.UIConnector;
import com.vaadin.shared.AbstractComponentState;
@@ -55,6 +54,8 @@ public abstract class AbstractComponentConnector extends AbstractConnector

private boolean initialStateEvent = true;

private boolean tooltipListenersAttached = false;

/**
* The style names from getState().getStyles() which are currently applied
* to the widget.
@@ -67,14 +68,6 @@ public abstract class AbstractComponentConnector extends AbstractConnector
public AbstractComponentConnector() {
}

@Override
protected void init() {
super.init();

getConnection().getVTooltip().connectHandlersToWidget(getWidget());

}

/**
* Creates and returns the widget for this VPaintableWidget. This method
* should only be called once when initializing the paintable.
@@ -105,7 +98,11 @@ public abstract class AbstractComponentConnector extends AbstractConnector
@Override
public Widget getWidget() {
if (widget == null) {
Profiler.enter("AbstractComponentConnector.createWidget for "
+ Util.getSimpleName(this));
widget = createWidget();
Profiler.leave("AbstractComponentConnector.createWidget for "
+ Util.getSimpleName(this));
}

return widget;
@@ -123,6 +120,8 @@ public abstract class AbstractComponentConnector extends AbstractConnector

@Override
public void onStateChanged(StateChangeEvent stateChangeEvent) {
Profiler.enter("AbstractComponentConnector.onStateChanged");
Profiler.enter("AbstractComponentConnector.onStateChanged update id");
if (stateChangeEvent.hasPropertyChanged("id")) {
if (getState().id != null) {
getWidget().getElement().setId(getState().id);
@@ -130,17 +129,20 @@ public abstract class AbstractComponentConnector extends AbstractConnector
getWidget().getElement().removeAttribute("id");
}
}
Profiler.leave("AbstractComponentConnector.onStateChanged update id");

/*
* Disabled state may affect (override) tabindex so the order must be
* first setting tabindex, then enabled state (through super
* implementation).
*/
Profiler.enter("AbstractComponentConnector.onStateChanged update tab index");
if (getState() instanceof TabIndexState
&& getWidget() instanceof Focusable) {
((Focusable) getWidget())
.setTabIndex(((TabIndexState) getState()).tabIndex);
}
Profiler.leave("AbstractComponentConnector.onStateChanged update tab index");

super.onStateChanged(stateChangeEvent);

@@ -154,7 +156,20 @@ public abstract class AbstractComponentConnector extends AbstractConnector

updateComponentSize();

Profiler.enter("AbstractComponentContainer.onStateChanged check tooltip");
if (!tooltipListenersAttached && hasTooltip()) {
/*
* Add event handlers for tooltips if they are needed but have not
* yet been added.
*/
tooltipListenersAttached = true;
getConnection().getVTooltip().connectHandlersToWidget(getWidget());
}
Profiler.leave("AbstractComponentContainer.onStateChanged check tooltip");

initialStateEvent = false;

Profiler.leave("AbstractComponentConnector.onStateChanged");
}

@Override
@@ -182,6 +197,8 @@ public abstract class AbstractComponentConnector extends AbstractConnector
}

private void updateComponentSize() {
Profiler.enter("AbstractComponentConnector.updateComponentSize");

String newWidth = getState().width == null ? "" : getState().width;
String newHeight = getState().height == null ? "" : getState().height;

@@ -209,11 +226,17 @@ public abstract class AbstractComponentConnector extends AbstractConnector
// Set defined sizes
Widget widget = getWidget();

Profiler.enter("AbstractComponentConnector.updateComponentSize update styleNames");
widget.setStyleName("v-has-width", !isUndefinedWidth());
widget.setStyleName("v-has-height", !isUndefinedHeight());
Profiler.leave("AbstractComponentConnector.updateComponentSize update styleNames");

Profiler.enter("AbstractComponentConnector.updateComponentSize update DOM");
widget.setHeight(newHeight);
widget.setWidth(newWidth);
Profiler.leave("AbstractComponentConnector.updateComponentSize update DOM");

Profiler.leave("AbstractComponentConnector.updateComponentSize");
}

@Override
@@ -257,10 +280,12 @@ public abstract class AbstractComponentConnector extends AbstractConnector
* </p>
*/
protected void updateWidgetStyleNames() {
Profiler.enter("AbstractComponentConnector.updateWidgetStyleNames");
AbstractComponentState state = getState();

String primaryStyleName = getWidget().getStylePrimaryName();
if (state.primaryStyleName != null) {
if (state.primaryStyleName != null
&& !state.primaryStyleName.equals(primaryStyleName)) {
/*
* We overwrite the widgets primary stylename if state defines a
* primary stylename.
@@ -302,7 +327,7 @@ public abstract class AbstractComponentConnector extends AbstractConnector
}

}
Profiler.leave("AbstractComponentConnector.updateWidgetStyleNames");
}

/**
@@ -394,17 +419,51 @@ public abstract class AbstractComponentConnector extends AbstractConnector
}
}

/*
* (non-Javadoc)
/**
* {@inheritDoc}
*
* <p>
* When overriding this method, {@link #hasTooltip()} should also be
* overridden to return true in all situations where this method might
* return a non-empty result.
* </p>
*
* @see com.vaadin.client.ComponentConnector#getTooltipInfo(com.
* google.gwt.dom.client.Element)
* @see ComponentConnector#getTooltipInfo(Element)
*/
@Override
public TooltipInfo getTooltipInfo(Element element) {
return new TooltipInfo(getState().description, getState().errorMessage);
}

/**
* Check whether there might be a tooltip for this component. The framework
* will only add event listeners for automatically handling tooltips (using
* {@link #getTooltipInfo(Element)}) if this method returns true.
*
* @return <code>true</code> if some part of the component might have a
* tooltip, otherwise <code>false</code>
*/
private boolean hasTooltip() {
/*
* Hack to avoid breaking backwards compatibility - use a generator to
* know whether there's a custom implementation of getTooltipInfo, and
* in that case always assume that there might be tooltip.
*/
if (TypeDataStore.getHasGetTooltipInfo(getClass())) {
return true;
}

// Normally, there is a tooltip if description or errorMessage is set
AbstractComponentState state = getState();
if (state.description != null && !state.description.equals("")) {
return true;
} else if (state.errorMessage != null && !state.errorMessage.equals("")) {
return true;
} else {
return false;
}
}

/**
* Gets the icon set for this component.
*

+ 4
- 0
client/src/com/vaadin/client/ui/AbstractConnector.java View File

@@ -218,6 +218,7 @@ public abstract class AbstractConnector implements ServerConnector,
}
if (statePropertyHandlerManagers != null
&& event instanceof StateChangeEvent) {
Profiler.enter("AbstractConnector.fireEvent statePropertyHandlerManagers");
StateChangeEvent stateChangeEvent = (StateChangeEvent) event;
JsArrayString keys = statePropertyHandlerManagers.getKeys();
for (int i = 0; i < keys.length(); i++) {
@@ -226,6 +227,7 @@ public abstract class AbstractConnector implements ServerConnector,
statePropertyHandlerManagers.get(property).fireEvent(event);
}
}
Profiler.leave("AbstractConnector.fireEvent statePropertyHandlerManagers");
}
if (Profiler.isEnabled()) {
Profiler.leave(profilerKey);
@@ -400,6 +402,7 @@ public abstract class AbstractConnector implements ServerConnector,
if (lastEnabledState == enabledState) {
return;
}
Profiler.enter("AbstractConnector.updateEnabledState");
lastEnabledState = enabledState;

for (ServerConnector c : getChildren()) {
@@ -407,6 +410,7 @@ public abstract class AbstractConnector implements ServerConnector,
// their parent
c.updateEnabledState(c.isEnabled());
}
Profiler.leave("AbstractConnector.updateEnabledState");
}

/**

+ 7
- 4
client/src/com/vaadin/client/ui/VAbsoluteLayout.java View File

@@ -326,6 +326,10 @@ public class VAbsoluteLayout extends ComplexPanel {

Style wrapperStyle = wrapper.getElement().getStyle();
Style widgetStyle = wrapper.getWidget().getElement().getStyle();

// Ensure previous heights do not affect the measures
wrapperStyle.clearHeight();

if (widgetStyle.getHeight() != null
&& widgetStyle.getHeight().endsWith("%")) {
int h;
@@ -343,8 +347,6 @@ public class VAbsoluteLayout extends ComplexPanel {
- wrapper.getElement().getOffsetTop();
}
wrapperStyle.setHeight(h, Unit.PX);
} else {
wrapperStyle.clearHeight();
}

wrapper.updateCaptionPosition();
@@ -380,6 +382,9 @@ public class VAbsoluteLayout extends ComplexPanel {
Style wrapperStyle = wrapper.getElement().getStyle();
Style widgetStyle = wrapper.getWidget().getElement().getStyle();

// Ensure previous heights do not affect the measures
wrapperStyle.clearWidth();

if (widgetStyle.getWidth() != null
&& widgetStyle.getWidth().endsWith("%")) {
int w;
@@ -398,8 +403,6 @@ public class VAbsoluteLayout extends ComplexPanel {
- wrapper.getElement().getOffsetLeft();
}
wrapperStyle.setWidth(w, Unit.PX);
} else {
wrapperStyle.clearWidth();
}

wrapper.updateCaptionPosition();

+ 4
- 0
client/src/com/vaadin/client/ui/VCssLayout.java View File

@@ -18,6 +18,7 @@ package com.vaadin.client.ui;

import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.Profiler;
import com.vaadin.client.StyleConstants;

/**
@@ -41,12 +42,15 @@ public class VCssLayout extends FlowPanel {
* For internal use only. May be removed or replaced in the future.
*/
public void addOrMove(Widget child, int index) {
Profiler.enter("VCssLayout.addOrMove");
if (child.getParent() == this) {
int currentIndex = getWidgetIndex(child);
if (index == currentIndex) {
Profiler.leave("VCssLayout.addOrMove");
return;
}
}
insert(child, index);
Profiler.leave("VCssLayout.addOrMove");
}
}

+ 432
- 76
client/src/com/vaadin/client/ui/VScrollTable.java View File

@@ -1191,6 +1191,39 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
return totalRows;
}

/**
* Returns the extra space that is given to the header column when column
* width is determined by header text.
*
* @return extra space in pixels
*/
private int getHeaderPadding() {
return scrollBody.getCellExtraWidth();
}

/**
* This method exists for the needs of {@link VTreeTable} only. Not part of
* the official API, <b>extend at your own risk</b>. May be removed or
* replaced in the future.
*
* @return index of TreeTable's hierarchy column, or -1 if not applicable
*/
protected int getHierarchyColumnIndex() {
return -1;
}

/**
* For internal use only. May be removed or replaced in the future.
*/
public void updateMaxIndent() {
int oldIndent = scrollBody.getMaxIndent();
scrollBody.calculateMaxIndent();
if (oldIndent != scrollBody.getMaxIndent()) {
// indent updated, headers might need adjusting
triggerLazyColumnAdjustment(true);
}
}

/** For internal use only. May be removed or replaced in the future. */
public void focusRowFromBody() {
if (selectedRowKeys.size() == 1) {
@@ -1382,6 +1415,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
* amount of rows in data set
*/
public void updateBody(UIDL uidl, int firstRow, int reqRows) {
int oldIndent = scrollBody.getMaxIndent();
if (uidl == null || reqRows < 1) {
// container is empty, remove possibly existing rows
if (firstRow <= 0) {
@@ -1399,6 +1433,11 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
scrollBody.renderRows(uidl, firstRow, reqRows);

discardRowsOutsideCacheWindow();
scrollBody.calculateMaxIndent();
if (oldIndent != scrollBody.getMaxIndent()) {
// indent updated, headers might need adjusting
headerChangedDuringUpdate = true;
}
}

/** For internal use only. May be removed or replaced in the future. */
@@ -1591,31 +1630,55 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
return tHead.getHeaderCell(index).getColKey();
}

private void setColWidth(int colIndex, int w, boolean isDefinedWidth) {
/**
* Note: not part of the official API, extend at your own risk. May be
* removed or replaced in the future.
*
* Sets the indicated column's width for headers and scrollBody alike.
*
* @param colIndex
* index of the modified column
* @param w
* new width (may be subject to modifications if doesn't meet
* minimum requirements)
* @param isDefinedWidth
* disables expand ratio if set true
*/
protected void setColWidth(int colIndex, int w, boolean isDefinedWidth) {
final HeaderCell hcell = tHead.getHeaderCell(colIndex);

// Make sure that the column grows to accommodate the sort indicator if
// necessary.
if (w < hcell.getMinWidth()) {
w = hcell.getMinWidth();
// get min width with no indent or padding
int minWidth = hcell.getMinWidth(false, false);
if (w < minWidth) {
w = minWidth;
}

// Set header column width
// Set header column width WITHOUT INDENT
hcell.setWidth(w, isDefinedWidth);

// Set footer column width likewise
FooterCell fcell = tFoot.getFooterCell(colIndex);
fcell.setWidth(w, isDefinedWidth);

// Ensure indicators have been taken into account
tHead.resizeCaptionContainer(hcell);

// Make sure that the body column grows to accommodate the indent if
// necessary.
// get min width with indent, no padding
minWidth = hcell.getMinWidth(true, false);
if (w < minWidth) {
w = minWidth;
}

// Set body column width
scrollBody.setColWidth(colIndex, w);

// Set footer column width
FooterCell fcell = tFoot.getFooterCell(colIndex);
fcell.setWidth(w, isDefinedWidth);
}

private int getColWidth(String colKey) {
return tHead.getHeaderCell(colKey).getWidth();
return tHead.getHeaderCell(colKey).getWidthWithIndent();
}

/**
@@ -1813,22 +1876,37 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
tHead.enableBrowserIntelligence();
tFoot.enableBrowserIntelligence();

int hierarchyColumnIndent = scrollBody != null ? scrollBody
.getMaxIndent() : 0;
HeaderCell hierarchyHeaderWithExpandRatio = null;

// first loop: collect natural widths
while (headCells.hasNext()) {
final HeaderCell hCell = (HeaderCell) headCells.next();
final FooterCell fCell = (FooterCell) footCells.next();
boolean needsIndent = hierarchyColumnIndent > 0
&& hCell.isHierarchyColumn();
int w = hCell.getWidth();
if (hCell.isDefinedWidth()) {
// server has defined column width explicitly
if (needsIndent && w < hierarchyColumnIndent) {
// hierarchy indent overrides explicitly set width
w = hierarchyColumnIndent;
}
totalExplicitColumnsWidths += w;
} else {
if (hCell.getExpandRatio() > 0) {
expandRatioDivider += hCell.getExpandRatio();
w = 0;
if (needsIndent && w < hierarchyColumnIndent) {
hierarchyHeaderWithExpandRatio = hCell;
// don't add to widths here, because will be included in
// the expand ratio space if there's enough of it
}
} else {
// get and store greater of header width and column width,
// and
// store it as a minimumn natural col width
// and store it as a minimum natural column width (these
// already contain the indent if any)
int headerWidth = hCell.getNaturalColumnWidth(i);
int footerWidth = fCell.getNaturalColumnWidth(i);
w = headerWidth > footerWidth ? headerWidth : footerWidth;
@@ -1840,6 +1918,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
total += w;
i++;
}
if (hierarchyHeaderWithExpandRatio != null) {
total += hierarchyColumnIndent;
}

tHead.disableBrowserIntelligence();
tFoot.disableBrowserIntelligence();
@@ -1871,13 +1952,24 @@ public class VScrollTable extends FlowPanel implements HasWidgets,

if (availW > total) {
// natural size is smaller than available space
final int extraSpace = availW - total;
int extraSpace = availW - total;
if (hierarchyHeaderWithExpandRatio != null) {
/*
* add the indent's space back to ensure each column gets an
* even share according to the expand ratios (note: if the
* allocated space isn't enough for the hierarchy column it
* shall be treated like a defined width column and the indent
* space gets removed from the extra space again)
*/
extraSpace += hierarchyColumnIndent;
}
final int totalWidthR = total - totalExplicitColumnsWidths;
int checksum = 0;

if (extraSpace == 1) {
// We cannot divide one single pixel so we give it the first
// undefined column
// no need to worry about indent here
headCells = tHead.iterator();
i = 0;
checksum = availW;
@@ -1891,6 +1983,22 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}

} else if (expandRatioDivider > 0) {
boolean setIndentToHierarchyHeader = false;
if (hierarchyHeaderWithExpandRatio != null) {
// ensure first that the hierarchyColumn gets at least the
// space allocated for indent
final int newSpace = Math
.round((extraSpace * (hierarchyHeaderWithExpandRatio
.getExpandRatio() / expandRatioDivider)));
if (newSpace < hierarchyColumnIndent) {
// not enough space for indent, remove indent from the
// extraSpace again and handle hierarchy column's header
// separately
setIndentToHierarchyHeader = true;
extraSpace -= hierarchyColumnIndent;
}
}

// visible columns have some active expand ratios, excess
// space is divided according to them
headCells = tHead.iterator();
@@ -1899,9 +2007,17 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
HeaderCell hCell = (HeaderCell) headCells.next();
if (hCell.getExpandRatio() > 0) {
int w = widths[i];
final int newSpace = Math.round((extraSpace * (hCell
.getExpandRatio() / expandRatioDivider)));
w += newSpace;
if (setIndentToHierarchyHeader
&& hierarchyHeaderWithExpandRatio.equals(hCell)) {
// hierarchy column's header is no longer part of
// the expansion divide and only gets indent
w += hierarchyColumnIndent;
} else {
final int newSpace = Math
.round((extraSpace * (hCell
.getExpandRatio() / expandRatioDivider)));
w += newSpace;
}
widths[i] = w;
}
checksum += widths[i];
@@ -1911,6 +2027,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
// no expand ratios defined, we will share extra space
// relatively to "natural widths" among those without
// explicit width
// no need to worry about indent here, it's already included
headCells = tHead.iterator();
i = 0;
while (headCells.hasNext()) {
@@ -1946,7 +2063,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}

} else {
// bodys size will be more than available and scrollbar will appear
// body's size will be more than available and scrollbar will appear
}

// last loop: set possibly modified values or reset if new tBody
@@ -2046,8 +2163,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}

/**
* Note, this method is not official api although declared as protected.
* Extend at you own risk.
* Note: this method is not part of official API although declared as
* protected. Extend at your own risk.
*
* @return true if content area will have scrollbars visible.
*/
@@ -2430,6 +2547,16 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
expandRatio = 0;
}

/**
* Sets width to the header cell. This width should not include any
* possible indent modifications that are present in
* {@link VScrollTableBody#getMaxIndent()}.
*
* @param w
* required width of the cell sans indentations
* @param ensureDefinedWidth
* disables expand ratio if required
*/
public void setWidth(int w, boolean ensureDefinedWidth) {
if (ensureDefinedWidth) {
definedWidth = true;
@@ -2453,15 +2580,23 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
* unless TD width is not explicitly set.
*/
if (scrollBody != null) {
int tdWidth = width + scrollBody.getCellExtraWidth();
int maxIndent = scrollBody.getMaxIndent();
if (w < maxIndent && isHierarchyColumn()) {
w = maxIndent;
}
int tdWidth = w + scrollBody.getCellExtraWidth();
setWidth(tdWidth + "px");
} else {
Scheduler.get().scheduleDeferred(new Command() {

@Override
public void execute() {
int tdWidth = width
+ scrollBody.getCellExtraWidth();
int maxIndent = scrollBody.getMaxIndent();
int tdWidth = width;
if (tdWidth < maxIndent && isHierarchyColumn()) {
tdWidth = maxIndent;
}
tdWidth += scrollBody.getCellExtraWidth();
setWidth(tdWidth + "px");
}
});
@@ -2484,10 +2619,45 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
return definedWidth && width >= 0;
}

/**
* This method exists for the needs of {@link VTreeTable} only.
*
* Returns the pixels width of the header cell. This includes the
* indent, if applicable.
*
* @return The width in pixels
*/
protected int getWidthWithIndent() {
if (scrollBody != null && isHierarchyColumn()) {
int maxIndent = scrollBody.getMaxIndent();
if (maxIndent > width) {
return maxIndent;
}
}
return width;
}

/**
* Returns the pixels width of the header cell.
*
* @return The width in pixels
*/
public int getWidth() {
return width;
}

/**
* This method exists for the needs of {@link VTreeTable} only.
*
* @return <code>true</code> if this is hierarcyColumn's header cell,
* <code>false</code> otherwise
*/
private boolean isHierarchyColumn() {
int hierarchyColumnIndex = getHierarchyColumnIndex();
return hierarchyColumnIndex >= 0
&& tHead.visibleCells.indexOf(this) == hierarchyColumnIndex;
}

public void setText(String headerText) {
DOM.setInnerHTML(captionContainer, headerText);
}
@@ -2742,7 +2912,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
DOM.setCapture(getElement());
dragStartX = DOM.eventGetClientX(event);
colIndex = getColIndexByKey(cid);
originalWidth = getWidth();
originalWidth = getWidthWithIndent();
DOM.eventPreventDefault(event);
break;
case Event.ONMOUSEUP:
@@ -2774,8 +2944,11 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
tHead.disableAutoColumnWidthCalculation(this);

int newWidth = originalWidth + deltaX;
if (newWidth < getMinWidth()) {
newWidth = getMinWidth();
// get min width with indent, no padding
int minWidth = getMinWidth(true, false);
if (newWidth < minWidth) {
// already includes indent if any
newWidth = minWidth;
}
setColWidth(colIndex, newWidth, true);
triggerLazyColumnAdjustment(false);
@@ -2787,12 +2960,37 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
}

public int getMinWidth() {
int cellExtraWidth = 0;
/**
* Returns the smallest possible cell width in pixels.
*
* @param includeIndent
* - width should include hierarchy column indent if
* applicable (VTreeTable only)
* @param includeCellExtraWidth
* - width should include paddings etc.
* @return
*/
private int getMinWidth(boolean includeIndent,
boolean includeCellExtraWidth) {
int minWidth = sortIndicator.getOffsetWidth();
if (scrollBody != null) {
cellExtraWidth += scrollBody.getCellExtraWidth();
// check the need for indent before adding paddings etc.
if (includeIndent && isHierarchyColumn()) {
int maxIndent = scrollBody.getMaxIndent();
if (minWidth < maxIndent) {
minWidth = maxIndent;
}
}
if (includeCellExtraWidth) {
minWidth += scrollBody.getCellExtraWidth();
}
}
return cellExtraWidth + sortIndicator.getOffsetWidth();
return minWidth;
}

public int getMinWidth() {
// get min width with padding, no indent
return getMinWidth(false, true);
}

public String getCaption() {
@@ -2823,16 +3021,20 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
* @return
*/
public int getNaturalColumnWidth(int columnIndex) {
final int iw = columnIndex == getHierarchyColumnIndex() ? scrollBody
.getMaxIndent() : 0;
if (isDefinedWidth()) {
if (iw > width) {
return iw;
}
return width;
} else {
if (naturalWidth < 0) {
// This is recently revealed column. Try to detect a proper
// value (greater of header and data
// cols)
// value (greater of header and data columns)

int hw = captionContainer.getOffsetWidth()
+ scrollBody.getCellExtraWidth();
+ getHeaderPadding();
if (BrowserInfo.get().isGecko()) {
hw += sortIndicator.getOffsetWidth();
}
@@ -2848,7 +3050,13 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
final int cw = scrollBody.getColWidth(columnIndex);
naturalWidth = (hw > cw ? hw : cw);
}
return naturalWidth;
if (iw > naturalWidth) {
// indent is temporary value, naturalWidth shouldn't be
// updated
return iw;
} else {
return naturalWidth;
}
}
}

@@ -2945,32 +3153,49 @@ public class VScrollTable extends FlowPanel implements HasWidgets,

public void resizeCaptionContainer(HeaderCell cell) {
HeaderCell lastcell = getHeaderCell(visibleCells.size() - 1);
int columnSelectorOffset = columnSelector.getOffsetWidth();

// Measure column widths
int columnTotalWidth = 0;
for (Widget w : visibleCells) {
columnTotalWidth += w.getOffsetWidth();
}

if (cell == lastcell
&& columnSelector.getOffsetWidth() > 0
&& columnTotalWidth >= div.getOffsetWidth()
- columnSelector.getOffsetWidth()
if (cell == lastcell && columnSelectorOffset > 0
&& !hasVerticalScrollbar()) {
// Ensure column caption is visible when placed under the column
// selector widget by shifting and resizing the caption.
int offset = 0;
int diff = div.getOffsetWidth() - columnTotalWidth;
if (diff < columnSelector.getOffsetWidth() && diff > 0) {
// If the difference is less than the column selectors width
// then just offset by the
// difference
offset = columnSelector.getOffsetWidth() - diff;

// Measure column widths
int columnTotalWidth = 0;
for (Widget w : visibleCells) {
int cellExtraWidth = w.getOffsetWidth();
if (scrollBody != null
&& visibleCells.indexOf(w) == getHierarchyColumnIndex()
&& cellExtraWidth < scrollBody.getMaxIndent()) {
// indent must be taken into consideration even if it
// hasn't been applied yet
columnTotalWidth += scrollBody.getMaxIndent();
} else {
columnTotalWidth += cellExtraWidth;
}
}

int divOffset = div.getOffsetWidth();
if (columnTotalWidth >= divOffset - columnSelectorOffset) {
/*
* Ensure column caption is visible when placed under the
* column selector widget by shifting and resizing the
* caption.
*/
int offset = 0;
int diff = divOffset - columnTotalWidth;
if (diff < columnSelectorOffset && diff > 0) {
/*
* If the difference is less than the column selectors
* width then just offset by the difference
*/
offset = columnSelectorOffset - diff;
} else {
// Else offset by the whole column selector
offset = columnSelectorOffset;
}
lastcell.resizeCaptionContainer(offset);
} else {
// Else offset by the whole column selector
offset = columnSelector.getOffsetWidth();
cell.resizeCaptionContainer(0);
}
lastcell.resizeCaptionContainer(offset);
} else {
cell.resizeCaptionContainer(0);
}
@@ -3033,10 +3258,14 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
// Make sure to accomodate for the sort indicator if
// necessary.
int width = Integer.parseInt(widthStr);
if (width < c.getMinWidth()) {
width = c.getMinWidth();
int widthWithoutAddedIndent = width;

// get min width with indent, no padding
int minWidth = c.getMinWidth(true, false);
if (width < minWidth) {
width = minWidth;
}
if (width != c.getWidth() && scrollBody != null) {
if (scrollBody != null && width != c.getWidthWithIndent()) {
// Do a more thorough update if a column is resized from
// the server *after* the header has been properly
// initialized
@@ -3052,7 +3281,13 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
});
refreshContentWidths = true;
} else {
c.setWidth(width, true);
// get min width with no indent or padding
minWidth = c.getMinWidth(false, false);
if (widthWithoutAddedIndent < minWidth) {
widthWithoutAddedIndent = minWidth;
}
// save min width without indent
c.setWidth(widthWithoutAddedIndent, true);
}
} else if (recalcWidths) {
c.setUndefinedWidth();
@@ -3507,12 +3742,14 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}

/**
* Sets the width of the cell
* Sets the width of the cell. This width should not include any
* possible indent modifications that are present in
* {@link VScrollTableBody#getMaxIndent()}.
*
* @param w
* The width of the cell
* @param ensureDefinedWidth
* Ensures the the given width is not recalculated
* Ensures that the given width is not recalculated
*/
public void setWidth(int w, boolean ensureDefinedWidth) {

@@ -3549,7 +3786,13 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
* unless TD width is not explicitly set.
*/
if (scrollBody != null) {
int tdWidth = width + scrollBody.getCellExtraWidth()
int maxIndent = scrollBody.getMaxIndent();
if (w < maxIndent
&& tFoot.visibleCells.indexOf(this) == getHierarchyColumnIndex()) {
// ensure there's room for the indent
w = maxIndent;
}
int tdWidth = w + scrollBody.getCellExtraWidth()
- borderWidths;
setWidth(Math.max(tdWidth, 0) + "px");
} else {
@@ -3557,8 +3800,14 @@ public class VScrollTable extends FlowPanel implements HasWidgets,

@Override
public void execute() {
int tdWidth = width
+ scrollBody.getCellExtraWidth()
int tdWidth = width;
int maxIndent = scrollBody.getMaxIndent();
if (tdWidth < maxIndent
&& tFoot.visibleCells.indexOf(this) == getHierarchyColumnIndex()) {
// ensure there's room for the indent
tdWidth = maxIndent;
}
tdWidth += scrollBody.getCellExtraWidth()
- borderWidths;
setWidth(Math.max(tdWidth, 0) + "px");
}
@@ -3571,6 +3820,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
* Sets the width to undefined
*/
public void setUndefinedWidth() {
definedWidth = false;
setWidth(-1, false);
}

@@ -3585,7 +3835,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}

/**
* Returns the pixels width of the footer cell
* Returns the pixels width of the footer cell.
*
* @return The width in pixels
*/
@@ -3699,7 +3949,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
* @return
*/
public int getNaturalColumnWidth(int columnIndex) {
final int iw = columnIndex == getHierarchyColumnIndex() ? scrollBody
.getMaxIndent() : 0;
if (isDefinedWidth()) {
if (iw > width) {
return iw;
}
return width;
} else {
if (naturalWidth < 0) {
@@ -3708,7 +3963,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
// cols)

final int hw = ((Element) getElement().getLastChild())
.getOffsetWidth() + scrollBody.getCellExtraWidth();
.getOffsetWidth() + getHeaderPadding();
if (columnIndex < 0) {
columnIndex = 0;
for (Iterator<Widget> it = tHead.iterator(); it
@@ -3721,7 +3976,11 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
final int cw = scrollBody.getColWidth(columnIndex);
naturalWidth = (hw > cw ? hw : cw);
}
return naturalWidth;
if (iw > naturalWidth) {
return iw;
} else {
return naturalWidth;
}
}
}

@@ -4627,6 +4886,28 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
return cellExtraWidth;
}

/**
* This method exists for the needs of {@link VTreeTable} only. May be
* removed or replaced in the future.</br> </br> Returns the maximum
* indent of the hierarcyColumn, if applicable.
*
* @see {@link VScrollTable#getHierarchyColumnIndex()}
*
* @return maximum indent in pixels
*/
protected int getMaxIndent() {
return 0;
}

/**
* This method exists for the needs of {@link VTreeTable} only. May be
* removed or replaced in the future.</br> </br> Calculates the maximum
* indent of the hierarcyColumn, if applicable.
*/
protected void calculateMaxIndent() {
// NOP
}

private void detectExtrawidth() {
NodeList<TableRowElement> rows = tBodyElement.getRows();
if (rows.getLength() == 0) {
@@ -4806,8 +5087,23 @@ public class VScrollTable extends FlowPanel implements HasWidgets,

protected void setCellWidth(int cellIx, int width) {
final Element cell = DOM.getChild(getElement(), cellIx);
cell.getFirstChildElement().getStyle()
.setPropertyPx("width", width);
Style wrapperStyle = cell.getFirstChildElement().getStyle();
int wrapperWidth = width;
if (BrowserInfo.get().isWebkit()
|| BrowserInfo.get().isOpera10()) {
/*
* Some versions of Webkit and Opera ignore the width
* definition of zero width table cells. Instead, use 1px
* and compensate with a negative margin.
*/
if (width == 0) {
wrapperWidth = 1;
wrapperStyle.setMarginRight(-1, Unit.PX);
} else {
wrapperStyle.clearMarginRight();
}
}
wrapperStyle.setPropertyPx("width", wrapperWidth);
cell.getStyle().setPropertyPx("width", width);
}

@@ -5866,7 +6162,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
@Override
public void execute() {
if (showRowHeaders) {
setCellWidth(0, tHead.getHeaderCell(0).getWidth());
setCellWidth(0, tHead.getHeaderCell(0)
.getWidthWithIndent());
calcAndSetSpanWidthOnCell(1);
} else {
calcAndSetSpanWidthOnCell(0);
@@ -6100,14 +6397,35 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
int totalExplicitColumnsWidths = 0;
float expandRatioDivider = 0;
int colIndex = 0;

int hierarchyColumnIndent = scrollBody.getMaxIndent();
int hierarchyColumnIndex = getHierarchyColumnIndex();
HeaderCell hierarchyHeaderInNeedOfFurtherHandling = null;

while (headCells.hasNext()) {
final HeaderCell hCell = (HeaderCell) headCells.next();
boolean hasIndent = hierarchyColumnIndent > 0
&& hCell.isHierarchyColumn();
if (hCell.isDefinedWidth()) {
totalExplicitColumnsWidths += hCell.getWidth();
usedMinimumWidth += hCell.getWidth();
// get width without indent to find out whether adjustments
// are needed (requires special handling further ahead)
int w = hCell.getWidth();
if (hasIndent && w < hierarchyColumnIndent) {
// enforce indent if necessary
w = hierarchyColumnIndent;
hierarchyHeaderInNeedOfFurtherHandling = hCell;
}
totalExplicitColumnsWidths += w;
usedMinimumWidth += w;
} else {
usedMinimumWidth += hCell.getNaturalColumnWidth(colIndex);
// natural width already includes indent if any
int naturalColumnWidth = hCell
.getNaturalColumnWidth(colIndex);
usedMinimumWidth += naturalColumnWidth;
expandRatioDivider += hCell.getExpandRatio();
if (hasIndent) {
hierarchyHeaderInNeedOfFurtherHandling = hCell;
}
}
colIndex++;
}
@@ -6152,6 +6470,28 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
int totalUndefinedNaturalWidths = usedMinimumWidth
- totalExplicitColumnsWidths;

if (hierarchyHeaderInNeedOfFurtherHandling != null
&& !hierarchyHeaderInNeedOfFurtherHandling.isDefinedWidth()) {
// ensure the cell gets enough space for the indent
int w = hierarchyHeaderInNeedOfFurtherHandling
.getNaturalColumnWidth(hierarchyColumnIndex);
int newSpace = Math.round(w + (float) extraSpace * (float) w
/ totalUndefinedNaturalWidths);
if (newSpace >= hierarchyColumnIndent) {
// no special handling required
hierarchyHeaderInNeedOfFurtherHandling = null;
} else {
// treat as a defined width column of indent's width
totalExplicitColumnsWidths += hierarchyColumnIndent;
usedMinimumWidth -= w - hierarchyColumnIndent;
totalUndefinedNaturalWidths = usedMinimumWidth
- totalExplicitColumnsWidths;
expandRatioDivider += hierarchyHeaderInNeedOfFurtherHandling
.getExpandRatio();
extraSpace = Math.max(availW - usedMinimumWidth, 0);
}
}

// we have some space that can be divided optimally
HeaderCell hCell;
colIndex = 0;
@@ -6167,7 +6507,10 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
newSpace = Math.round((w + extraSpace
* hCell.getExpandRatio() / expandRatioDivider));
} else {
if (totalUndefinedNaturalWidths != 0) {
if (hierarchyHeaderInNeedOfFurtherHandling == hCell) {
// still exists, so needs exactly the indent's width
newSpace = hierarchyColumnIndent;
} else if (totalUndefinedNaturalWidths != 0) {
// divide relatively to natural column widths
newSpace = Math.round(w + (float) extraSpace
* (float) w / totalUndefinedNaturalWidths);
@@ -6177,8 +6520,21 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
checksum += newSpace;
setColWidth(colIndex, newSpace, false);

} else {
checksum += hCell.getWidth();
if (hierarchyHeaderInNeedOfFurtherHandling == hCell) {
// defined with enforced into indent width
checksum += hierarchyColumnIndent;
setColWidth(colIndex, hierarchyColumnIndent, false);
} else {
int cellWidth = hCell.getWidthWithIndent();
checksum += cellWidth;
if (hCell.isHierarchyColumn()) {
// update in case the indent has changed
// (not detectable earlier)
setColWidth(colIndex, cellWidth, true);
}
}
}
colIndex++;
}
@@ -6194,8 +6550,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
while (headCells.hasNext()) {
HeaderCell hc = (HeaderCell) headCells.next();
if (!hc.isDefinedWidth()) {
setColWidth(colIndex,
hc.getWidth() + availW - checksum, false);
setColWidth(colIndex, hc.getWidthWithIndent() + availW
- checksum, false);
break;
}
colIndex++;

+ 6
- 9
client/src/com/vaadin/client/ui/VTextField.java View File

@@ -272,19 +272,16 @@ public class VTextField extends TextBoxBase implements Field, ChangeHandler,

/** For internal use only. May be removed or replaced in the future. */
public void setMaxLength(int newMaxLength) {
if (newMaxLength >= 0 && newMaxLength != maxLength) {
maxLength = newMaxLength;
updateMaxLength(maxLength);
} else if (maxLength != -1) {
maxLength = -1;
updateMaxLength(maxLength);
if (newMaxLength == maxLength) {
return;
}

maxLength = newMaxLength;
updateMaxLength(maxLength);
}

/**
* This method is reponsible for updating the DOM or otherwise ensuring that
* the given max length is enforced. Called when the max length for the
* 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

+ 32
- 6
client/src/com/vaadin/client/ui/VTreeTable.java View File

@@ -122,8 +122,14 @@ public class VTreeTable extends VScrollTable {
}
}

@Override
protected int getHierarchyColumnIndex() {
return colIndexOfHierarchy + (showRowHeaders ? 1 : 0);
}

public class VTreeTableScrollBody extends VScrollTable.VScrollTableBody {
private int indentWidth = -1;
private int maxIndent = 0;

VTreeTableScrollBody() {
super();
@@ -232,6 +238,11 @@ public class VTreeTable extends VScrollTable {
treeSpacer.getParentElement().getStyle()
.setPaddingLeft(getIndent(), Unit.PX);
treeSpacer.getStyle().setWidth(getIndent(), Unit.PX);
int colWidth = getColWidth(getHierarchyColumnIndex());
if (colWidth > 0 && getIndent() > colWidth) {
VTreeTable.this.setColWidth(getHierarchyColumnIndex(),
getIndent(), false);
}
}
}

@@ -277,16 +288,12 @@ public class VTreeTable extends VScrollTable {
// hierarchy column
int indent = getIndent();
if (indent != -1) {
width = Math.max(width - getIndent(), 0);
width = Math.max(width - indent, 0);
}
}
super.setCellWidth(cellIx, width);
}

private int getHierarchyColumnIndex() {
return colIndexOfHierarchy + (showRowHeaders ? 1 : 0);
}

private int getIndent() {
return (depth + 1) * getIndentWidth();
}
@@ -323,7 +330,8 @@ public class VTreeTable extends VScrollTable {
@Override
public void execute() {
if (showRowHeaders) {
setCellWidth(0, tHead.getHeaderCell(0).getWidth());
setCellWidth(0, tHead.getHeaderCell(0)
.getWidthWithIndent());
calcAndSetSpanWidthOnCell(1);
} else {
calcAndSetSpanWidthOnCell(0);
@@ -421,6 +429,22 @@ public class VTreeTable extends VScrollTable {
return indentWidth;
}

@Override
protected int getMaxIndent() {
return maxIndent;
}

@Override
protected void calculateMaxIndent() {
int maxIndent = 0;
Iterator<Widget> iterator = iterator();
while (iterator.hasNext()) {
VTreeTableRow next = (VTreeTableRow) iterator.next();
maxIndent = Math.max(maxIndent, next.getIndent());
}
this.maxIndent = maxIndent;
}

private void detectIndent(VTreeTableRow vTreeTableRow) {
indentWidth = vTreeTableRow.treeSpacer.getOffsetWidth();
if (indentWidth == 0) {
@@ -432,6 +456,7 @@ public class VTreeTable extends VScrollTable {
VTreeTableRow next = (VTreeTableRow) iterator.next();
next.setIndent();
}
calculateMaxIndent();
}

protected void unlinkRowsAnimatedAndUpdateCacheWhenFinished(
@@ -471,6 +496,7 @@ public class VTreeTable extends VScrollTable {
RowExpandAnimation anim = new RowExpandAnimation(insertedRows);
anim.run(150);
}
scrollBody.calculateMaxIndent();
return insertedRows;
}


+ 3
- 0
client/src/com/vaadin/client/ui/VUI.java View File

@@ -41,6 +41,7 @@ import com.vaadin.client.ComponentConnector;
import com.vaadin.client.ConnectorMap;
import com.vaadin.client.Focusable;
import com.vaadin.client.LayoutManager;
import com.vaadin.client.Profiler;
import com.vaadin.client.VConsole;
import com.vaadin.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner;
import com.vaadin.client.ui.TouchScrollDelegate.TouchScrollHandler;
@@ -395,11 +396,13 @@ public class VUI extends SimplePanel implements ResizeHandler,
* For internal use only. May be removed or replaced in the future.
*/
public void sendClientResized() {
Profiler.enter("VUI.sendClientResized");
Element parentElement = getElement().getParentElement();
int viewHeight = parentElement.getClientHeight();
int viewWidth = parentElement.getClientWidth();

ResizeEvent.fire(this, viewWidth, viewHeight);
Profiler.leave("VUI.sendClientResized");
}

public native static void goTo(String url)

+ 6
- 0
client/src/com/vaadin/client/ui/label/LabelConnector.java View File

@@ -17,6 +17,7 @@ package com.vaadin.client.ui.label;

import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.PreElement;
import com.vaadin.client.Profiler;
import com.vaadin.client.Util;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.ui.AbstractComponentConnector;
@@ -44,6 +45,7 @@ public class LabelConnector extends AbstractComponentConnector {
public void onStateChanged(StateChangeEvent stateChangeEvent) {
super.onStateChanged(stateChangeEvent);
boolean sinkOnloads = false;
Profiler.enter("LabelConnector.onStateChanged update content");
switch (getState().contentMode) {
case PREFORMATTED:
PreElement preElement = Document.get().createPreElement();
@@ -69,8 +71,12 @@ public class LabelConnector extends AbstractComponentConnector {
break;

}
Profiler.leave("LabelConnector.onStateChanged update content");

if (sinkOnloads) {
Profiler.enter("LabelConnector.onStateChanged sinkOnloads");
Util.sinkOnloadForImages(getWidget().getElement());
Profiler.leave("LabelConnector.onStateChanged sinkOnloads");
}
}


+ 5
- 1
client/src/com/vaadin/client/ui/link/LinkConnector.java View File

@@ -42,7 +42,11 @@ public class LinkConnector extends AbstractComponentConnector implements
@Override
public void onStateChanged(StateChangeEvent stateChangeEvent) {
getWidget().src = getResourceUrl(LinkConstants.HREF_RESOURCE);
getWidget().anchor.setAttribute("href", getWidget().src);
if (getWidget().src == null) {
getWidget().anchor.removeAttribute("href");
} else {
getWidget().anchor.setAttribute("href", getWidget().src);
}
}
});
}

+ 1
- 0
client/src/com/vaadin/client/ui/table/TableConnector.java View File

@@ -176,6 +176,7 @@ public class TableConnector extends AbstractHasComponentsConnector implements
// amount of rows)
getWidget().scrollBody.setLastRendered(getWidget().scrollBody
.getLastRendered());
getWidget().updateMaxIndent();
} else {
getWidget().postponeSanityCheckForLastRendered = false;
UIDL rowData = uidl.getChildByTagName("rows");

+ 8
- 0
client/src/com/vaadin/client/ui/tabsheet/TabsheetBaseConnector.java View File

@@ -89,6 +89,14 @@ public abstract class TabsheetBaseConnector extends
}
}

// Detach any old tab widget, should be max 1
for (Iterator<Widget> iterator = oldWidgets.iterator(); iterator
.hasNext();) {
Widget oldWidget = iterator.next();
if (oldWidget.isAttached()) {
oldWidget.removeFromParent();
}
}
}

@Override

+ 4
- 2
client/src/com/vaadin/client/ui/textfield/TextFieldConnector.java View File

@@ -77,8 +77,10 @@ public class TextFieldConnector extends AbstractFieldConnector implements
}
getWidget().setColumns(getState().columns);

final String text = getState().text;

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. Additional sanity check verifies there is no

+ 18
- 1
client/src/com/vaadin/client/ui/ui/UIConnector.java View File

@@ -20,6 +20,7 @@ import java.util.Iterator;
import java.util.List;

import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Position;
@@ -43,6 +44,7 @@ import com.vaadin.client.ConnectorHierarchyChangeEvent;
import com.vaadin.client.ConnectorMap;
import com.vaadin.client.Focusable;
import com.vaadin.client.Paintable;
import com.vaadin.client.TooltipInfo;
import com.vaadin.client.UIDL;
import com.vaadin.client.VConsole;
import com.vaadin.client.communication.StateChangeEvent;
@@ -312,7 +314,12 @@ public class UIConnector extends AbstractSingleComponentContainerConnector
if (firstPaint) {
// Queue the initial window size to be sent with the following
// request.
getWidget().sendClientResized();
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
getWidget().sendClientResized();
}
});
}
getWidget().rendering = false;
}
@@ -467,6 +474,16 @@ public class UIConnector extends AbstractSingleComponentContainerConnector
}
}

@Override
public TooltipInfo getTooltipInfo(com.google.gwt.dom.client.Element element) {
/*
* Override method to make AbstractComponentConnector.hasTooltip()
* return true so there's a top level handler that takes care of hiding
* tooltips whenever the mouse is moved somewhere else.
*/
return super.getTooltipInfo(element);
}

/**
* Tries to scroll the viewport so that the given connector is in view.
*

+ 29
- 6
common.xml View File

@@ -27,9 +27,12 @@
<union id="empty.reference" />

<property name="filtered.webcontent.dir" location="${vaadin.basedir}/result/filteredWebContent" />
<property name="release-notes-tickets-file" location="${vaadin.basedir}/result/release-notes-tickets.html" />

<target name="filter.webcontent" unless="webcontent.filtered">
<target name="filter.webcontent" unless="webcontent.filtered" depends="fetch-release-notes-tickets">
<property name="webcontent.filtered" value="true" />
<!-- Running without build.release-notes will cause an error, which is ignored -->
<loadfile property="release-notes-tickets" srcFile="${release-notes-tickets-file}" failonerror="false" />

<delete dir="${filtered.webcontent.dir}" />
<copy todir="${filtered.webcontent.dir}">
@@ -57,11 +60,21 @@
<replacetokens begintoken="@" endtoken="@">
<token key="builddate" value="${build.date}" />
</replacetokens>
<replacetokens begintoken="@" endtoken="@">
<token key="release-notes-tickets" value="${release-notes-tickets}" />
</replacetokens>
</filterchain>
</copy>
</target>


<target name="fetch-release-notes-tickets" unless="built.release-notes" if="build.release-notes">
<mkdir dir="${vaadin.basedir}/result"/>
<subant buildpath="${vaadin.basedir}/buildhelpers" target="fetch-release-notes-tickets" antfile="build.xml" inheritall="true">
<property name="output" location="${release-notes-tickets-file}" />
</subant>
<property name="built.release-notes" value="1" />
</target>

<fileset dir="${filtered.webcontent.dir}" id="common.files.for.all.jars">
<patternset>
<include name="release-notes.html" />
@@ -110,7 +123,7 @@
</target>


<target name="sources.jar" depends="compile">
<target name="sources.jar" depends="compile, filter.webcontent">
<fail unless="result.dir" message="No result.dir parameter given" />
<fail unless="module.name" message="No module.name parameter given" />
<fail unless="src" message="No src directory parameter given" />
@@ -132,7 +145,7 @@

</target>

<target name="javadoc.jar" depends="dependencies">
<target name="javadoc.jar" depends="dependencies, filter.webcontent">
<fail unless="result.dir" message="No result.dir parameter given" />
<fail unless="module.name" message="No module.name parameter given" />
<property name="src" location="{$result.dir}/../src" />
@@ -157,7 +170,7 @@

</target>

<target name="jar" depends="compile, pom.xml">
<target name="jar" depends="compile, pom.xml, filter.webcontent">
<fail unless="result.dir" message="No result.dir parameter given" />
<fail unless="module.name" message="No module.name parameter given" />

@@ -261,6 +274,16 @@
</javac>
</target>

<target name="exec-buildhelper" depends="compile">
<fail unless="main.class" message="No main class given in 'main.class'" />
<fail unless="output" message="No output file given in 'output'" />
<java classname="${main.class}" output="${output}" failonerror="true" fork="yes">
<classpath refid="vaadin.buildhelpers.classpath" />
<classpath refid="classpath.compile.dependencies" />
<jvmarg value="-Dvaadin.version=${vaadin.version}" />
</java>
</target>

<target name="directories">
<property name="result.dir" location="result" />
<property name="src" location="${result.dir}/../src" />
@@ -321,7 +344,7 @@
</copy>
</target>

<target name="dependencies" description="Resolves dependencies needed by this module" depends="filter.webcontent">
<target name="dependencies" description="Resolves dependencies needed by this module">
<property name='conf' value="build, build-provided" />
<ivy:resolve resolveid="common" conf="${conf}" />
<ivy:cachepath pathid="classpath.compile.dependencies" conf="${conf}" />

+ 7
- 0
server/src/com/vaadin/ui/CheckBox.java View File

@@ -110,6 +110,13 @@ public class CheckBox extends AbstractField<Boolean> {
return (CheckBoxState) super.getState();
}

/*
* Overridden to keep the shared state in sync with the AbstractField
* internal value. Should be removed once AbstractField is refactored to use
* shared state.
*
* See tickets #10921 and #11064.
*/
@Override
protected void setInternalValue(Boolean newValue) {
super.setInternalValue(newValue);

+ 15
- 0
server/src/com/vaadin/ui/ProgressIndicator.java View File

@@ -157,4 +157,19 @@ public class ProgressIndicator extends AbstractField<Float> implements
return getState().pollingInterval;
}

/*
* Overridden to keep the shared state in sync with the AbstractField
* internal value. Should be removed once AbstractField is refactored to use
* shared state.
*
* See tickets #10921 and #11064.
*/
@Override
protected void setInternalValue(Float newValue) {
super.setInternalValue(newValue);
if (newValue == null) {
newValue = 0.0f;
}
getState().state = newValue;
}
}

+ 16
- 0
server/src/com/vaadin/ui/Slider.java View File

@@ -263,6 +263,22 @@ public class Slider extends AbstractField<Double> {
getState().value = newFieldValue;
}

/*
* Overridden to keep the shared state in sync with the AbstractField
* internal value. Should be removed once AbstractField is refactored to use
* shared state.
*
* See tickets #10921 and #11064.
*/
@Override
protected void setInternalValue(Double newValue) {
super.setInternalValue(newValue);
if (newValue == null) {
newValue = 0.0;
}
getState().value = newValue;
}

/**
* Thrown when the value of the slider is about to be set to a value that is
* outside the valid range of the slider.

+ 27
- 0
server/src/com/vaadin/ui/Tree.java View File

@@ -414,6 +414,9 @@ public class Tree extends AbstractSelect implements Container.Hierarchical,
final Object id = itemIdMapper.get(keys[i]);
if (id != null && isExpanded(id)) {
expanded.remove(id);
if (expandedItemId == id) {
expandedItemId = null;
}
fireCollapseEvent(id);
}
}
@@ -841,6 +844,10 @@ public class Tree extends AbstractSelect implements Container.Hierarchical,
super.setContainerDataSource(new ContainerHierarchicalWrapper(
newDataSource));
}

// Ensure previous expanded items are cleaned up if they don't exist in
// the new container
cleanupExpandedItems();
}

/* Expand event and listener */
@@ -1670,4 +1677,24 @@ public class Tree extends AbstractSelect implements Container.Hierarchical,
return itemDescriptionGenerator;
}

@Override
public void containerItemSetChange(
com.vaadin.data.Container.ItemSetChangeEvent event) {

// Ensure removed items are cleaned up from expanded list
cleanupExpandedItems();

super.containerItemSetChange(event);
}

private void cleanupExpandedItems() {
for (Object expandedItemId : expanded) {
if (getItem(expandedItemId) == null) {
expanded.remove(expandedItemId);
if (this.expandedItemId == expandedItemId) {
this.expandedItemId = null;
}
}
}
}
}

+ 62
- 0
server/tests/src/com/vaadin/tests/server/component/tree/TreeTest.java View File

@@ -1,5 +1,8 @@
package com.vaadin.tests.server.component.tree;

import java.lang.reflect.Field;
import java.util.HashSet;

import junit.framework.TestCase;

import com.vaadin.data.Container;
@@ -71,4 +74,63 @@ public class TreeTest extends TestCase {
assertTrue(Container.Hierarchical.class.isAssignableFrom(tree4
.getContainerDataSource().getClass()));
}

public void testRemoveExpandedItems() throws Exception {
tree.expandItem("parent");
tree.expandItem("child");

Field expandedField = tree.getClass()
.getDeclaredField("expanded");
Field expandedItemIdField = tree.getClass().getDeclaredField(
"expandedItemId");

expandedField.setAccessible(true);
expandedItemIdField.setAccessible(true);

HashSet<Object> expanded = (HashSet<Object>) expandedField.get(tree);
Object expandedItemId = expandedItemIdField.get(tree);

assertEquals(2, expanded.size());
assertTrue("Contains parent", expanded.contains("parent"));
assertTrue("Contains child", expanded.contains("child"));
assertEquals("child", expandedItemId);

tree.removeItem("parent");

expanded = (HashSet<Object>) expandedField.get(tree);
expandedItemId = expandedItemIdField.get(tree);

assertEquals(1, expanded.size());
assertTrue("Contains child", expanded.contains("child"));
assertEquals("child", expandedItemId);

tree.removeItem("child");

expanded = (HashSet<Object>) expandedField.get(tree);
expandedItemId = expandedItemIdField.get(tree);

assertEquals(0, expanded.size());
assertNull(expandedItemId);
}

public void testRemoveExpandedItemsOnContainerChange() throws Exception {
tree.expandItem("parent");
tree.expandItem("child");

tree.setContainerDataSource(new HierarchicalContainer());

Field expandedField = tree.getClass().getDeclaredField("expanded");
Field expandedItemIdField = tree.getClass().getDeclaredField(
"expandedItemId");

expandedField.setAccessible(true);
expandedItemIdField.setAccessible(true);

HashSet<Object> expanded = (HashSet<Object>) expandedField.get(tree);
assertEquals(0, expanded.size());

Object expandedItemId = expandedItemIdField.get(tree);
assertNull(expandedItemId);
}

}

+ 1121
- 1144
theme-compiler/src/com/vaadin/sass/internal/parser/Parser.java
File diff suppressed because it is too large
View File


+ 31
- 20
theme-compiler/src/com/vaadin/sass/internal/parser/Parser.jj View File

@@ -319,10 +319,12 @@ public class Parser implements org.w3c.css.sac.Parser {
String encoding = source.getEncoding();
InputStream input = source.getByteStream();
if (!input.markSupported()) {
// If mark is not supported, wrap it in a stream which supports mark
input = new BufferedInputStream(input);
source.setByteStream(input);
input.mark(100);
}
// Mark either the original stream or the wrapped stream
input.mark(100);
if(encoding == null){
encoding = "ASCII";
@@ -1056,9 +1058,6 @@ void skipUnknownRule() :
| n=<UNICODERANGE>
| n=<URL>
| n=";"
| n="+"
| n=">"
| n="~"
| n="-"
| n=<UNKNOWN>
) {
@@ -1081,13 +1080,18 @@ char combinator() :
char connector = ' ';
}
{
"+" ( <S> )* { return '+'; }
| ">" ( <S> )* { return '>'; }
| "~" ( <S> )* { return '~'; }
| <S> ( ( "+" { connector = '+'; }
| ">" { connector = '>'; }
| "~" { connector = '~'; } )
( <S> )* )? { return connector; }
(connector = combinatorChar()
| <S> (connector = combinatorChar())?) { return connector; }
}

/**to refactor combinator and reuse in selector().*/
char combinatorChar() :
{Token t;}
{
(t = <PLUS> | t = <PRECEDES> | t = <SIBLING>) (<S>)*
{
return t.image.charAt(0);
}
}

void microsoftExtension() :
@@ -1200,12 +1204,14 @@ void styleRule() :
*/
String selector() :
{
String selector;
String selector = null;
char comb;
}
{
try {
selector=simple_selector(null, ' ')
// the selector can begin either a simple_selector, or a combinatorChar(+, >, ~).
// when beginning with combinatorChar, the next one should be a simple_selector().
(selector=simple_selector(null, ' ') | (comb=combinatorChar() selector=simple_selector(selector, comb)))
( LOOKAHEAD(2) comb=combinator()
selector=simple_selector(selector, comb) )* (<S>)*
{
@@ -1265,22 +1271,27 @@ String simple_selector(String selector, char comb) :
if (cond != null) {
simple_current = simple_current + cond;
}
if (selector != null) {
switch (comb) {
StringBuilder builder = new StringBuilder();
switch (comb) {
case ' ':
selector = selector + comb + simple_current;
if(selector!=null){
builder.append(selector).append(" ");
}
break;
case '+':
case '>':
case '~':
selector = selector + " " + comb + " " + simple_current;
if(selector!=null){
builder.append(selector).append(" ");
}
builder.append(comb).append(" ");
break;
default:
throw new ParseException("invalid state. send a bug report");
}
} else {
selector= simple_current;
}
builder.append(simple_current);
selector = builder.toString();
if (pseudoElt != null) {
selector = selector + pseudoElt;
}

+ 15
- 15
theme-compiler/src/com/vaadin/sass/internal/parser/ParserTokenManager.java View File

@@ -1,3 +1,18 @@
/*
* Copyright 2000-2013 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.
*/
/* Generated By:JavaCC: Do not edit this line. ParserTokenManager.java */
package com.vaadin.sass.internal.parser;

@@ -5835,21 +5850,6 @@ public class ParserTokenManager implements ParserConstants {
int jjmatchedPos;
int jjmatchedKind;

/*
* Copyright 2000-2013 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.
*/
/** Get the next Token. */
public Token getNextToken() {
Token specialToken = null;

+ 26
- 5
theme-compiler/src/com/vaadin/sass/internal/visitor/MixinNodeHandler.java View File

@@ -108,18 +108,39 @@ public class MixinNodeHandler {
}
}
}

int i = 0;
for (final LexicalUnitImpl unit : remainingUnits) {
checkExtraParameters(mixinNode, remainingNodes.size(),
remainingUnits.size());
for (int i = 0; i < remainingNodes.size()
&& i < remainingUnits.size(); i++) {
LexicalUnitImpl unit = remainingUnits.get(i);
remainingNodes.get(i).setExpr(
(LexicalUnitImpl) DeepCopy.copy(unit));
i++;
}

}

}

protected static void checkExtraParameters(MixinNode mixinNode,
int remainingNodesSize, int remainingUnitsSize) {
if (remainingUnitsSize > remainingNodesSize) {
String fileName = null;
Node root = mixinNode.getParentNode();
while (root != null && !(root instanceof ScssStylesheet)) {
root = root.getParentNode();
}
if (root != null) {
fileName = ((ScssStylesheet) root).getFileName();
}
StringBuilder builder = new StringBuilder();
builder.append("More parameters than expected, in Mixin ").append(
mixinNode.getName());
if (fileName != null) {
builder.append(", in file ").append(fileName);
}
throw new RuntimeException(builder.toString());
}
}

private static void replaceChildVariables(MixinDefNode mixinDef, Node node) {
for (final Node child : node.getChildren()) {
replaceChildVariables(mixinDef, child);

+ 9
- 0
theme-compiler/tests/resources/automatic/css/nested-selector-begin-with-plus.css View File

@@ -0,0 +1,9 @@
.v-panel {
display: block;
max-width: 84em;
margin: auto;
}
.v-panel + .abc {
margin-top: 1em;
}

+ 9
- 0
theme-compiler/tests/resources/automatic/scss/nested-selector-begin-with-plus.scss View File

@@ -0,0 +1,9 @@
.v-panel {
display: block;
max-width: 84em;
margin: auto;
+ .abc {
margin-top: 1em;
}
}

theme-compiler/tests/resources/sasslangbroken/css/95-test_nested_selector_with_child_selector_hack_extender_and_sibling_selector_extendee.css → theme-compiler/tests/resources/sasslang/css/95-test_nested_selector_with_child_selector_hack_extender_and_sibling_selector_extendee.css View File


theme-compiler/tests/resources/sasslangbroken/scss/95-test_nested_selector_with_child_selector_hack_extender_and_sibling_selector_extendee.scss → theme-compiler/tests/resources/sasslang/scss/95-test_nested_selector_with_child_selector_hack_extender_and_sibling_selector_extendee.scss View File


+ 4
- 0
theme-compiler/tests/resources/scss/mixin-extra-params.scss View File

@@ -0,0 +1,4 @@
@mixin test ($p1) {
color: $p1;
}
@include test(foo, bar);

+ 25
- 0
theme-compiler/tests/src/com/vaadin/sass/testcases/scss/MixinExtraParameters.java View File

@@ -0,0 +1,25 @@
package com.vaadin.sass.testcases.scss;

import org.junit.Assert;
import org.junit.Test;

import com.vaadin.sass.AbstractTestBase;
import com.vaadin.sass.internal.ScssStylesheet;

public class MixinExtraParameters extends AbstractTestBase {
String scss = "/scss/mixin-extra-params.scss";

@Test
public void testCompiler() {
ScssStylesheet sheet;
try {
sheet = getStyleSheet(scss);
sheet.compile();
} catch (RuntimeException e) {
Assert.assertEquals(e.getMessage(),
"More parameters than expected, in Mixin test");
} catch (Exception e) {
Assert.fail();
}
}
}

+ 4
- 0
uitest/build.xml View File

@@ -106,6 +106,10 @@
<path refid="classpath.runtime.dependencies" />
</copy>


<!-- Ensure filtered webcontent files are available -->
<antcall target="common.filter.webcontent" />

<war destfile="${result.war}" duplicate="fail" index="true">
<fileset refid="common.files.for.all.jars" />
<fileset dir="${result.dir}">

+ 37
- 0
uitest/src/com/vaadin/tests/components/absolutelayout/AbsoluteLayoutResizing.html View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="selenium.base" href="http://localhost:8888/" />
<title>New Test</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">New Test</td></tr>
</thead><tbody>
<tr>
<td>open</td>
<td>/run/com.vaadin.tests.components.absolutelayout.AbsoluteLayoutResizing?restartApplication</td>
<td></td>
</tr>
<tr>
<td>dragAndDrop</td>
<td>vaadin=runcomvaadintestscomponentsabsolutelayoutAbsoluteLayoutResizing::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VSplitPanelVertical[0]/domChild[0]/domChild[1]/domChild[0]</td>
<td>0,294</td>
</tr>
<tr>
<td>dragAndDrop</td>
<td>vaadin=runcomvaadintestscomponentsabsolutelayoutAbsoluteLayoutResizing::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VSplitPanelVertical[0]/VSplitPanelHorizontal[0]/domChild[0]/domChild[1]/domChild[0]</td>
<td>588,0</td>
</tr>
<tr>
<td>screenCapture</td>
<td></td>
<td>resized</td>
</tr>

</tbody></table>
</body>
</html>

+ 44
- 0
uitest/src/com/vaadin/tests/components/absolutelayout/AbsoluteLayoutResizing.java View File

@@ -0,0 +1,44 @@
package com.vaadin.tests.components.absolutelayout;

import com.vaadin.tests.components.TestBase;
import com.vaadin.ui.AbsoluteLayout;
import com.vaadin.ui.HorizontalSplitPanel;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.VerticalSplitPanel;

public class AbsoluteLayoutResizing extends TestBase {

@Override
protected void setup() {
getLayout().setSizeFull();

AbsoluteLayout al = new AbsoluteLayout();

TextArea ta = new TextArea();
ta.setValue("When resizing the layout this text area should also get resized");
ta.setSizeFull();
al.addComponent(ta, "left: 10px; right: 10px; top: 10px; bottom: 10px;");

HorizontalSplitPanel horizPanel = new HorizontalSplitPanel();
horizPanel.setSizeFull();
horizPanel.setFirstComponent(al);

VerticalSplitPanel vertPanel = new VerticalSplitPanel();
vertPanel.setSizeFull();
vertPanel.setFirstComponent(horizPanel);

addComponent(vertPanel);

}

@Override
protected String getDescription() {
return "Absolute layout should correctly dynamically resize itself";
}

@Override
protected Integer getTicketNumber() {
return 10427;
}

}

+ 32
- 0
uitest/src/com/vaadin/tests/components/slider/SliderValueFromDataSource.html View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="selenium.base" href="http://localhost:8070/" />
<title>SliderValueFromDataSource</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">SliderValueFromDataSource</td></tr>
</thead><tbody>
<tr>
<td>open</td>
<td>/run/SliderValueFromDataSource?restartApplication</td>
<td></td>
</tr>
<tr>
<td>assertAttribute</td>
<td>vaadin=runSliderValueFromDataSource::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VProgressIndicator[0]/domChild[0]/domChild[0]@style</td>
<td>regex:.*(width|WIDTH): 50%.*</td>
</tr>
<tr>
<td>assertAttribute</td>
<td>vaadin=runSliderValueFromDataSource::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VSlider[0]/domChild[2]/domChild[0]@style</td>
<td>regex:.*(margin-left|MARGIN-LEFT): 94px.*</td>
</tr>

</tbody></table>
</body>
</html>

+ 59
- 0
uitest/src/com/vaadin/tests/components/slider/SliderValueFromDataSource.java View File

@@ -0,0 +1,59 @@
package com.vaadin.tests.components.slider;

import com.vaadin.data.Item;
import com.vaadin.data.util.BeanItem;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.ui.ProgressIndicator;
import com.vaadin.ui.Slider;

public class SliderValueFromDataSource extends AbstractTestUI {

public static class TestBean {

private double doubleValue = 10.0;
private float floatValue = 0.5f;

public double getDoubleValue() {
return doubleValue;
}

public void setDoubleValue(double doubleValue) {
this.doubleValue = doubleValue;
}

public float getFloatValue() {
return floatValue;
}

public void setFloatValue(float floatValue) {
this.floatValue = floatValue;
}
}

@Override
protected void setup(VaadinRequest request) {
Item item = new BeanItem<TestBean>(new TestBean());

Slider slider = new Slider(0, 20);
slider.setWidth("200px");
slider.setPropertyDataSource(item.getItemProperty("doubleValue"));
addComponent(slider);

ProgressIndicator pi = new ProgressIndicator();
pi.setPollingInterval(60 * 1000);
pi.setWidth("200px");
pi.setPropertyDataSource(item.getItemProperty("floatValue"));
addComponent(pi);
}

@Override
protected String getTestDescription() {
return "Slider and ProgressIndicator do not properly pass a value from data source to the client";
}

@Override
protected Integer getTicketNumber() {
return 10921;
}
}

+ 51
- 0
uitest/src/com/vaadin/tests/components/textfield/TextFieldMaxLengthRemovedFromDOM.html View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="selenium.base" href="http://localhost:8888/" />
<title>New Test</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">New Test</td></tr>
</thead><tbody>
<tr>
<td>open</td>
<td>/run/com.vaadin.tests.components.textfield.TextFieldMaxLengthRemovedFromDOM?restartApplication</td>
<td></td>
</tr>
<tr>
<td>assertAttribute</td>
<td>vaadin=runcomvaadintestscomponentstextfieldTextFieldMaxLengthRemovedFromDOM::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTextField[0]@maxlength</td>
<td>11</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstextfieldTextFieldMaxLengthRemovedFromDOM::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTextField[0]</td>
<td>118,13</td>
</tr>
<tr>
<td>assertAttribute</td>
<td>vaadin=runcomvaadintestscomponentstextfieldTextFieldMaxLengthRemovedFromDOM::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTextField[0]@maxlength</td>
<td>11</td>
</tr>
<tr>
<td>type</td>
<td>vaadin=runcomvaadintestscomponentstextfieldTextFieldMaxLengthRemovedFromDOM::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTextField[0]</td>
<td>hello</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstextfieldTextFieldMaxLengthRemovedFromDOM::/VVerticalLayout[0]/domChild[0]</td>
<td>172,60</td>
</tr>
<tr>
<td>assertAttribute</td>
<td>vaadin=runcomvaadintestscomponentstextfieldTextFieldMaxLengthRemovedFromDOM::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTextField[0]@maxlength</td>
<td>11</td>
</tr>
</tbody></table>
</body>
</html>

+ 37
- 0
uitest/src/com/vaadin/tests/components/textfield/TextFieldMaxLengthRemovedFromDOM.java View File

@@ -0,0 +1,37 @@
package com.vaadin.tests.components.textfield;

import com.vaadin.event.FieldEvents;
import com.vaadin.event.FieldEvents.FocusEvent;
import com.vaadin.tests.components.TestBase;
import com.vaadin.ui.TextField;

public class TextFieldMaxLengthRemovedFromDOM extends TestBase {

@Override
protected void setup() {
final TextField tf = new TextField();
tf.setMaxLength(11);
tf.setRequired(true);
tf.setImmediate(true);
addComponent(tf);

tf.addFocusListener(new FieldEvents.FocusListener() {

public void focus(FocusEvent event) {
// Resetting Max length should not remove maxlength attribute
tf.setMaxLength(11);
}
});
}

@Override
protected String getDescription() {
return "Maxlength attribute should not dissappear from the DOM when I focus the text field.";
}

@Override
protected Integer getTicketNumber() {
return 9940;
}

}

+ 31
- 0
uitest/src/com/vaadin/tests/components/textfield/TextFieldWithDataSourceAndInputPrompt.html View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="selenium.base" href="http://localhost:8888/" />
<title>New Test</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">New Test</td></tr>
</thead><tbody>
<tr>
<td>open</td>
<td>/run/com.vaadin.tests.components.textfield.TextFieldWithDataSourceAndInputPrompt?restartApplication</td>
<td></td>
</tr>
<tr>
<td>assertValue</td>
<td>vaadin=runcomvaadintestscomponentstextfieldTextFieldWithDataSourceAndInputPrompt::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTextField[0]</td>
<td>Me is input prompt</td>
</tr>
<tr>
<td>assertValue</td>
<td>vaadin=runcomvaadintestscomponentstextfieldTextFieldWithDataSourceAndInputPrompt::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VTextField[0]</td>
<td>Me is input prompt</td>
</tr>
</tbody></table>
</body>
</html>

+ 63
- 0
uitest/src/com/vaadin/tests/components/textfield/TextFieldWithDataSourceAndInputPrompt.java View File

@@ -0,0 +1,63 @@
/*
* Copyright 2012 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.tests.components.textfield;

import com.vaadin.data.util.BeanItem;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.ui.TextField;

public class TextFieldWithDataSourceAndInputPrompt extends AbstractTestUI {
public static class Pojo {
private String string;

public String getString() {
return string;
}

public void setString(String string) {
this.string = string;
}
}

@Override
protected void setup(VaadinRequest request) {
TextField textField = new TextField("TextField with null value");
textField.setInputPrompt("Me is input prompt");
textField.setNullRepresentation(null);
textField.setValue(null);
addComponent(textField);

TextField textField2 = new TextField(
"TextField with null data source value");
textField2.setInputPrompt("Me is input prompt");
textField2.setNullRepresentation(null);
BeanItem<Pojo> beanItem = new BeanItem<Pojo>(new Pojo());
textField2.setPropertyDataSource(beanItem.getItemProperty("string"));
addComponent(textField2);
}

@Override
protected String getTestDescription() {
return "Input prompt should be shown when data source provides null";
}

@Override
protected Integer getTicketNumber() {
return 11021;
}

}

+ 69
- 0
uitest/src/com/vaadin/tests/components/treetable/TreeTableExtraScrollBarWithChildren.html View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="selenium.base" href="" />
<title>TreeTableExtraScrollbar</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">TreeTableExtraScrollbar</td></tr>
</thead><tbody>
<tr>
<td>open</td>
<td>/run/com.vaadin.tests.components.treetable.TreeTableExtraScrollbarWithChildren?restartApplication</td>
<td></td>
</tr>
<tr>
<td>mouseClick</td>
<td>button</td>
<td></td>
</tr>
<tr>
<td>pause</td>
<td>300</td>
<td></td>
</tr>
<!-- screenCapture should not have a horizontal scrollbar, and the columns should be the same width in body and headers -->
<tr>
<td>screenCapture</td>
<td></td>
<td>expanded</td>
</tr>
<tr>
<td>mouseClick</td>
<td>button</td>
<td></td>
</tr>
<tr>
<td>pause</td>
<td>300</td>
<td></td>
</tr>
<!-- screenCapture should not have a horizontal scrollbar, the columns should be back to original width in body and headers, and vertical scrollbar shouldn't have left an empty space -->
<tr>
<td>screenCapture</td>
<td></td>
<td>collapsed</td>
</tr>
<tr>
<td>open</td>
<td>/run/com.vaadin.tests.components.treetable.TreeTableExtraScrollbarWithChildren</td>
<td></td>
</tr>
<tr>
<td>pause</td>
<td>300</td>
<td></td>
</tr>
<!-- screenCapture should not have changed -->
<tr>
<td>screenCapture</td>
<td></td>
<td>refreshed</td>
</tr>
</tbody></table>
</body>
</html>

+ 92
- 0
uitest/src/com/vaadin/tests/components/treetable/TreeTableExtraScrollbarWithChildren.java View File

@@ -0,0 +1,92 @@
package com.vaadin.tests.components.treetable;

import com.vaadin.tests.components.TestBase;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Notification;
import com.vaadin.ui.Table;
import com.vaadin.ui.TreeTable;

public class TreeTableExtraScrollbarWithChildren extends TestBase {

@Override
protected String getDescription() {
return "Arrow calculation should not cause a horizontal scrollbar"
+ " if there is enough space for the final contents.";
}

@Override
protected Integer getTicketNumber() {
return 10513;
}

@Override
protected void setup() {
HorizontalLayout layout = new HorizontalLayout();
layout.setWidth("300px");
layout.setHeight("300px");

final TreeTable table = new TreeTable();
table.setSizeFull();

table.addGeneratedColumn("parameterId", new HierarchyColumnGenerator());
table.addGeneratedColumn("wordingTextId", new TypeColumnGenerator());
table.addGeneratedColumn("parameterTypeId", new TypeColumnGenerator());

table.setColumnWidth("parameterId", 26);

table.addItem(new TestObject("name 1", "value 1"));
table.addItem(new TestObject("name 2", "value 2"));
table.addItem(new TestObject("name 3", "value 3"));
table.addItem(new TestObject("name 4", "value 4"));
table.addItem(new TestObject("name 5", "value 5"));
final TestObject parent = new TestObject("name 6", "value 6");
table.addItem(parent);
table.setFooterVisible(true);
for (int i = 1; i <= 10; ++i) {
TestObject child = new TestObject("name 6-" + i, "value 6-" + i);
table.addItem(child);
table.setParent(child, parent);
}
table.setVisibleColumns(new Object[] { "wordingTextId", "parameterId",
"parameterTypeId" });
table.setColumnHeaders(new String[] { "", "", "" });
table.setHierarchyColumn("parameterId");

layout.addComponent(table);

Button button = new Button("Toggle");
button.setId("button");
button.addClickListener(new ClickListener() {

public void buttonClick(ClickEvent event) {
table.setCollapsed(parent, !table.isCollapsed(parent));
Notification.show("collapsed: " + table.isCollapsed(parent));
}
});

addComponent(layout);
addComponent(button);
}

private class HierarchyColumnGenerator implements Table.ColumnGenerator {
public Object generateCell(Table table, Object itemId, Object columnId) {
Label label = new Label("this should be mostly hidden");
label.setSizeUndefined();
return label;
}
}

private class TypeColumnGenerator implements Table.ColumnGenerator {
public Object generateCell(Table table, Object itemId, Object columnId) {
if (itemId instanceof TestObject) {
return new Label(((TestObject) itemId).getValue());
}
return null;
}
}

}

+ 37
- 0
uitest/src/com/vaadin/tests/debug/HierarchyAfterAnalyzeLayouts.html View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="selenium.base" href="" />
<title>New Test</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">New Test</td></tr>
</thead><tbody>
<tr>
<td>open</td>
<td>/run/com.vaadin.tests.debug.HierarchyAfterAnalyzeLayouts?restartApplication&amp;debug</td>
<td></td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestsdebugHierarchyAfterAnalyzeLayouts::Root/VDebugConsole[0]/FlowPanel[0]/HorizontalPanel[0]/domChild[0]/domChild[0]/domChild[3]/domChild[0]</td>
<td>18,9</td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Layouts analyzed on server, total top level problems: 0</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>vaadin=runcomvaadintestsdebugHierarchyAfterAnalyzeLayouts::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td>
<td></td>
</tr>

</tbody></table>
</body>
</html>

+ 40
- 0
uitest/src/com/vaadin/tests/debug/HierarchyAfterAnalyzeLayouts.java View File

@@ -0,0 +1,40 @@
/*
* Copyright 2000-2013 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.tests.debug;

import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.ui.Label;

public class HierarchyAfterAnalyzeLayouts extends AbstractTestUI {

@Override
protected void setup(VaadinRequest request) {
addComponent(new Label("This is a label"));
}

@Override
protected String getTestDescription() {
return "The connector hierarchy should be in order after clicking AL in the debug console";
}

@Override
protected Integer getTicketNumber() {
return Integer.valueOf(11067);
}

}

+ 4
- 4
uitest/src/com/vaadin/tests/minitutorials/v7a1/CreatingPreserveState.java View File

@@ -18,6 +18,7 @@ package com.vaadin.tests.minitutorials.v7a1;

import com.vaadin.annotations.PreserveOnRefresh;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.CssLayout;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;

@@ -31,13 +32,12 @@ import com.vaadin.ui.UI;
*/
@PreserveOnRefresh
public class CreatingPreserveState extends UI {
private static int windowCounter = 0;
private static int instanceCounter = 0;

@Override
public void init(VaadinRequest request) {
TextField tf = new TextField("Window #" + (++windowCounter));
TextField tf = new TextField("Instance #" + (++instanceCounter));
tf.setImmediate(true);
setContent(tf);
setContent(new CssLayout(tf));
}

}

Loading…
Cancel
Save