From d6cf871c7d3cd7e48db3450b02361e24fe652670 Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Thu, 28 Feb 2013 13:10:09 +0200 Subject: Add bootstrap performance measuring support (#11188) svn changeset:25664/svn branch:6.8 Conflicts: client/src/com/vaadin/client/ApplicationConnection.java uitest/src/com/vaadin/tests/performance/BasicPerformanceTest.java uitest/src/com/vaadin/tests/util/TestUtils.java Change-Id: I699e7b47ad5a62b67dbdf1004da5e5daf009ba25 --- .../com/vaadin/client/ApplicationConnection.java | 25 +++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'client') diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java index 1a637e3161..ab9f95e8fd 100644 --- a/client/src/com/vaadin/client/ApplicationConnection.java +++ b/client/src/com/vaadin/client/ApplicationConnection.java @@ -16,7 +16,7 @@ package com.vaadin.client; -import java.util.ArrayList; +import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; @@ -500,6 +500,7 @@ public class ApplicationConnection { ap.@com.vaadin.client.ApplicationConnection::totalProcessingTime ]; pd = pd.concat(ap.@com.vaadin.client.ApplicationConnection::serverTimingInfo); + pd[pd.length] = ap.@com.vaadin.client.ApplicationConnection::bootstrapTime; return pd; }); @@ -513,6 +514,16 @@ public class ApplicationConnection { $wnd.vaadin.clients[TTAppId] = client; }-*/; + private static native final int calculateBootstrapTime() + /*-{ + if ($wnd.performance && $wnd.performance.timing) { + return (new Date).getTime() - $wnd.performance.timing.responseStart; + } else { + // performance.timing not supported + return -1; + } + }-*/; + /** * Helper for tt initialization */ @@ -947,6 +958,15 @@ public class ApplicationConnection { */ protected int totalProcessingTime; + /** + * Holds the time it took to load the page and render the first view. 0 + * means that this value has not yet been calculated because the first view + * has not yet been rendered (or that your browser is very fast). -1 means + * that the browser does not support the performance.timing feature used to + * get this measurement. + */ + private int bootstrapTime; + /** * Holds the timing information from the server-side. How much time was * spent servicing the last request and how much time has been spent @@ -1512,6 +1532,9 @@ public class ApplicationConnection { lastProcessingTime = (int) ((new Date().getTime()) - start .getTime()); totalProcessingTime += lastProcessingTime; + if (bootstrapTime == 0) { + bootstrapTime = calculateBootstrapTime(); + } VConsole.log(" Processing time was " + String.valueOf(lastProcessingTime) + "ms for " -- cgit v1.2.3 From 718b7dea773fddc47a316d82989e0759af6df67b Mon Sep 17 00:00:00 2001 From: John Ahlroos Date: Thu, 28 Feb 2013 09:31:32 +0200 Subject: Fixed scrolling jumping up to first row when adding rows and adjusting the currentPageFirstItem in the same UIDL request #10970 Change-Id: I54562e7e0c5429f3493892cf3a14380b0d15bbfd --- client/src/com/vaadin/client/ui/VScrollTable.java | 16 ++++++- .../components/table/TableRowScrolledBottom.html | 52 ++++++++++++++++++++ .../components/table/TableRowScrolledBottom.java | 55 ++++++++++++++++++++++ 3 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/table/TableRowScrolledBottom.html create mode 100644 uitest/src/com/vaadin/tests/components/table/TableRowScrolledBottom.java (limited to 'client') diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java index c76dd38d8f..6f9fd6da88 100644 --- a/client/src/com/vaadin/client/ui/VScrollTable.java +++ b/client/src/com/vaadin/client/ui/VScrollTable.java @@ -1098,6 +1098,14 @@ public class VScrollTable extends FlowPanel implements HasWidgets, } } + private ScheduledCommand lazyScroller = new ScheduledCommand() { + @Override + public void execute() { + int offsetTop = measureRowHeightOffset(firstvisible); + scrollBodyPanel.setScrollPosition(offsetTop); + } + }; + /** For internal use only. May be removed or replaced in the future. */ public void updateFirstVisibleAndScrollIfNeeded(UIDL uidl) { firstvisible = uidl.hasVariable("firstvisible") ? uidl @@ -1105,8 +1113,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets, if (firstvisible != lastRequestedFirstvisible && scrollBody != null) { // received 'surprising' firstvisible from server: scroll there firstRowInViewPort = firstvisible; - scrollBodyPanel - .setScrollPosition(measureRowHeightOffset(firstvisible)); + + /* + * Schedule the scrolling to be executed last so no updates to the rows + * affect scrolling measurements. + */ + Scheduler.get().scheduleFinally(lazyScroller); } } diff --git a/uitest/src/com/vaadin/tests/components/table/TableRowScrolledBottom.html b/uitest/src/com/vaadin/tests/components/table/TableRowScrolledBottom.html new file mode 100644 index 0000000000..e5b1f47f2d --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableRowScrolledBottom.html @@ -0,0 +1,52 @@ + + + + + + +New Test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
New Test
open/run/com.vaadin.tests.components.table.TableRowScrolledBottom?restartApplication
clickvaadin=runcomvaadintestscomponentstableTableRowScrolledBottom::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VButton[0]/domChild[0]
pause500
assertTextvaadin=runcomvaadintestscomponentstableTableRowScrolledBottom::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[44]/VLabel[0]This is a test item with long text so that there is something to see Nr. 100. This text must be long otherwise the timing issue on Firefox does not occur. This works fine in IE
clickvaadin=runcomvaadintestscomponentstableTableRowScrolledBottom::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VButton[0]/domChild[0]/domChild[0]
pause500
assertTextvaadin=runcomvaadintestscomponentstableTableRowScrolledBottom::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[44]/VLabel[0]This is a test item with long text so that there is something to see Nr. 200. This text must be long otherwise the timing issue on Firefox does not occur. This works fine in IE
+ + diff --git a/uitest/src/com/vaadin/tests/components/table/TableRowScrolledBottom.java b/uitest/src/com/vaadin/tests/components/table/TableRowScrolledBottom.java new file mode 100644 index 0000000000..9823fc1859 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableRowScrolledBottom.java @@ -0,0 +1,55 @@ +package com.vaadin.tests.components.table; + +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Button; +import com.vaadin.ui.Label; +import com.vaadin.ui.Table; +import com.vaadin.ui.VerticalLayout; + +public class TableRowScrolledBottom extends TestBase { + + @Override + protected void setup() { + + final Table table = new Table(); + table.setSizeFull(); + table.addContainerProperty("Test", Label.class, null); + table.setHeight("100%"); + + Button button = new Button("Add 100 items"); + button.addClickListener(new Button.ClickListener() { + int i = 0; + + @Override + public void buttonClick(Button.ClickEvent event) { + for (int j = 0; j < 100; j++) { + ++i; + table.addItem( + new Object[] { new Label( + "This is a test item with long text so that there is something to see Nr. " + + i + + ". This text must be long otherwise the timing issue on Firefox does not occur. This works fine in IE", + ContentMode.HTML) }, i); + table.setCurrentPageFirstItemIndex(table + .getContainerDataSource().size() - 1); + } + } + }); + + addComponent(table); + addComponent(button); + getLayout().setExpandRatio(table, 1f); + } + + @Override + protected String getDescription() { + return "Table should be scrolled to bottom when adding rows and updating currentPageFirstItemIndex to last item"; + } + + @Override + protected Integer getTicketNumber() { + return 10970; + } + +} -- cgit v1.2.3 From d4143dd71b314a83a8f610f6b5c9d06435180dbd Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 4 Mar 2013 20:07:00 +0200 Subject: Log errors as errors and not normal messages (#11251) Change-Id: I3686da461ea5b64b5051c2c3b24feb58814c929d --- client/src/com/vaadin/client/ui/embedded/EmbeddedConnector.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'client') diff --git a/client/src/com/vaadin/client/ui/embedded/EmbeddedConnector.java b/client/src/com/vaadin/client/ui/embedded/EmbeddedConnector.java index bce4242557..c6e4883fa9 100644 --- a/client/src/com/vaadin/client/ui/embedded/EmbeddedConnector.java +++ b/client/src/com/vaadin/client/ui/embedded/EmbeddedConnector.java @@ -137,7 +137,8 @@ public class EmbeddedConnector extends AbstractComponentConnector implements getWidget().getSrc(uidl, client)); clearBrowserElement = false; } else { - VConsole.log("Unknown Embedded type '" + getWidget().type + "'"); + VConsole.error("Unknown Embedded type '" + getWidget().type + + "'"); } } else if (uidl.hasAttribute("mimetype")) { // remove old style name related to type @@ -203,10 +204,10 @@ public class EmbeddedConnector extends AbstractComponentConnector implements .getStringAttribute(EmbeddedConstants.ALTERNATE_TEXT)); } } else { - VConsole.log("Unknown Embedded mimetype '" + mime + "'"); + VConsole.error("Unknown Embedded mimetype '" + mime + "'"); } } else { - VConsole.log("Unknown Embedded; no type or mimetype attribute"); + VConsole.error("Unknown Embedded; no type or mimetype attribute"); } if (clearBrowserElement) { -- cgit v1.2.3 From 276e6fc6c1d2643c77d0e4abea8cf862cd8b9718 Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Fri, 1 Mar 2013 18:17:57 +0200 Subject: Add performance.timing support to Profiler (#11188) Change-Id: I3fb14b1280a1ee8bfaa2aeab87b40c374d2e4443 --- .../com/vaadin/client/ApplicationConnection.java | 3 ++ client/src/com/vaadin/client/Profiler.java | 57 ++++++++++++++++++++++ 2 files changed, 60 insertions(+) (limited to 'client') diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java index ab9f95e8fd..2610530a80 100644 --- a/client/src/com/vaadin/client/ApplicationConnection.java +++ b/client/src/com/vaadin/client/ApplicationConnection.java @@ -1534,6 +1534,9 @@ public class ApplicationConnection { totalProcessingTime += lastProcessingTime; if (bootstrapTime == 0) { bootstrapTime = calculateBootstrapTime(); + if (Profiler.isEnabled() && bootstrapTime != -1) { + Profiler.logBootstrapTimings(); + } } VConsole.log(" Processing time was " diff --git a/client/src/com/vaadin/client/Profiler.java b/client/src/com/vaadin/client/Profiler.java index be26da859f..15de339572 100644 --- a/client/src/com/vaadin/client/Profiler.java +++ b/client/src/com/vaadin/client/Profiler.java @@ -362,4 +362,61 @@ public class Profiler { return false; } + /** + * Outputs the time passed since various events recored in + * performance.timing if supported by the browser. + */ + public static void logBootstrapTimings() { + if (isEnabled()) { + double now = Duration.currentTimeMillis(); + + StringBuilder stringBuilder = new StringBuilder( + "Time since window.performance.timing events"); + SimpleTree tree = new SimpleTree(stringBuilder.toString()); + + String[] keys = new String[] { "navigationStart", + "unloadEventStart", "unloadEventEnd", "redirectStart", + "redirectEnd", "fetchStart", "domainLookupStart", + "domainLookupEnd", "connectStart", "connectEnd", + "requestStart", "responseStart", "responseEnd", + "domLoading", "domInteractive", + "domContentLoadedEventStart", "domContentLoadedEventEnd", + "domComplete", "loadEventStart", "loadEventEnd" }; + + for (String key : keys) { + double value = getPerformanceTiming(key); + if (value == 0) { + // Ignore missing value + continue; + } + String text = key + ": " + (now - value); + tree.add(new Label(text)); + stringBuilder.append("\n * "); + stringBuilder.append(text); + } + + if (tree.getWidgetCount() == 0) { + VConsole.log("Bootstrap timings not supported, please ensure your browser supports performance.timing"); + return; + } + + Console implementation = VConsole.getImplementation(); + if (implementation instanceof VDebugConsole) { + VDebugConsole console = (VDebugConsole) implementation; + console.showTree(tree, stringBuilder.toString()); + } else { + VConsole.log(stringBuilder.toString()); + } + } + } + + private static final native double getPerformanceTiming(String name) + /*-{ + if ($wnd.performance && $wnd.performance.timing && $wnd.performance.timing[name]) { + return $wnd.performance.timing[name]; + } else { + return 0; + } + }-*/; + } -- cgit v1.2.3 From effe571067d7d238397b464aa367f6425a2ab2bf Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Wed, 6 Mar 2013 13:30:38 +0200 Subject: Profiler based on __gwtStatsEvent (#10960) * Bootstrap installs a __gwtStatsEvent implementation for tracking GWT's own bootstrap timing events * Profiler.enter and Profiler.leave use __gwtStatsEvent * Profiler data is displayed based on the data tracked by __gwtStatsEvent Change-Id: I3db05ca2622aecb745270f01d47cd71648e3bebd --- .../vaadin/client/ApplicationConfiguration.java | 2 +- client/src/com/vaadin/client/Profiler.java | 203 +++++++++++++++++---- server/src/com/vaadin/server/BootstrapHandler.java | 12 ++ 3 files changed, 176 insertions(+), 41 deletions(-) (limited to 'client') diff --git a/client/src/com/vaadin/client/ApplicationConfiguration.java b/client/src/com/vaadin/client/ApplicationConfiguration.java index 9ba660626e..2291f21361 100644 --- a/client/src/com/vaadin/client/ApplicationConfiguration.java +++ b/client/src/com/vaadin/client/ApplicationConfiguration.java @@ -535,7 +535,7 @@ public class ApplicationConfiguration implements EntryPoint { @Override public void onModuleLoad() { - Profiler.reset(); + Profiler.initialize(); Profiler.enter("ApplicationConfiguration.onModuleLoad"); BrowserInfo browserInfo = BrowserInfo.get(); diff --git a/client/src/com/vaadin/client/Profiler.java b/client/src/com/vaadin/client/Profiler.java index 15de339572..bbfdc981d1 100644 --- a/client/src/com/vaadin/client/Profiler.java +++ b/client/src/com/vaadin/client/Profiler.java @@ -54,25 +54,45 @@ public class Profiler { } } - private static JsArray events; + private static final String evtGroup = "VaadinProfiler"; - private static final class ProfilerEvent extends JavaScriptObject { - protected ProfilerEvent() { + private static final class GwtStatsEvent extends JavaScriptObject { + protected GwtStatsEvent() { // JSO constructor } - public native String getName() + private native String getEvtGroup() /*-{ - return this.name; + return this.evtGroup; }-*/; - private native double getRawTime() + private native double getMillis() /*-{ - return this.time; + return this.millis; }-*/; - private boolean isStart() { - return getRawTime() <= 0; + private native String getSubSystem() + /*-{ + return this.subSystem; + }-*/; + + private native String getType() + /*-{ + return this.type; + }-*/; + + private native String getModuleName() + /*-{ + return this.moduleName; + }-*/; + + public final String getEventName() { + String group = getEvtGroup(); + if (evtGroup.equals(group)) { + return getSubSystem(); + } else { + return group + "." + getSubSystem(); + } } } @@ -91,21 +111,17 @@ public class Profiler { return name; } - public Node addEvent(ProfilerEvent event) { - Node child = children.get(event.getName()); + private Node accessChild(String name, double time) { + Node child = children.get(name); if (child == null) { - child = new Node(event.getName()); - children.put(event.getName(), child); + child = new Node(name); + children.put(name, child); } - child.time += event.getRawTime(); + child.time -= time; child.count++; return child; } - public void registerEnd(ProfilerEvent event) { - time += event.getRawTime(); - } - public double getTimeSpent() { return time; } @@ -148,6 +164,11 @@ public class Profiler { } } + @Override + public String toString() { + return getStringRepresentation(""); + } + private String getStringRepresentation(String prefix) { if (getName() == null) { return ""; @@ -229,7 +250,7 @@ public class Profiler { */ public static void enter(String name) { if (isEnabled()) { - pushEvent(events, name, -Duration.currentTimeMillis()); + logGwtEvent(name, "begin"); } } @@ -243,14 +264,20 @@ public class Profiler { */ public static void leave(String name) { if (isEnabled()) { - pushEvent(events, name, Duration.currentTimeMillis()); + logGwtEvent(name, "end"); } } - private static native final void pushEvent(JsArray target, - String name, double time) + private static native final void logGwtEvent(String name, String type) /*-{ - target[target.length] = {name: name, time: time}; + $wnd.__gwtStatsEvent({ + evtGroup: @com.vaadin.client.Profiler::evtGroup, + moduleName: @com.google.gwt.core.client.GWT::getModuleName()(), + millis: (new Date).getTime(), + sessionId: undefined, + subSystem: name, + type: type + }); }-*/; /** @@ -259,7 +286,35 @@ public class Profiler { */ public static void reset() { if (isEnabled()) { - events = JavaScriptObject.createArray().cast(); + /* + * Old implementations might call reset for initialization, so + * ensure it is initialized here as well. Initialization has no side + * effects if already done. + */ + initialize(); + + clearEventsList(); + } + } + + /** + * Initializes the profiler. This should be done before calling any other + * function in this class. Failing to do so might cause undesired behavior. + * This method has no side effects if the initialization has already been + * done. + *

+ * Please note that this method should be called even if the profiler is not + * enabled because it will then remove a logger function that might have + * been included in the HTML page and that would leak memory unless removed. + *

+ * + * @since 7.0.2 + */ + public static void initialize() { + if (isEnabled()) { + ensureLogger(); + } else { + ensureNoLogger(); } } @@ -275,25 +330,52 @@ public class Profiler { LinkedList stack = new LinkedList(); Node rootNode = new Node(null); stack.add(rootNode); - for (int i = 0; i < events.length(); i++) { - ProfilerEvent event = events.get(i); - if (event.isStart()) { - Node stackTop = stack.getLast().addEvent(event); - stack.add(stackTop); - } else { - Node stackTop = stack.removeLast(); - if (stackTop == null) { - VConsole.error("Leaving " + event.getName() - + " that was never entered."); + JsArray gwtStatsEvents = getGwtStatsEvents(); + if (gwtStatsEvents.length() == 0) { + VConsole.log("No profiling events recorded, this might happen if another __gwtStatsEvent handler is installed."); + return; + } + + for (int i = 0; i < gwtStatsEvents.length(); i++) { + GwtStatsEvent gwtStatsEvent = gwtStatsEvents.get(i); + String eventName = gwtStatsEvent.getEventName(); + String type = gwtStatsEvent.getType(); + boolean isBeginEvent = "begin".equals(type); + + Node stackTop = stack.getLast(); + boolean inEvent = eventName.equals(stackTop.getName()) + && !isBeginEvent; + + if (!inEvent && stack.size() >= 2 + && eventName.equals(stack.get(stack.size() - 2).name) + && !isBeginEvent) { + // back out of sub event + stackTop.time += gwtStatsEvent.getMillis(); + stack.removeLast(); + stackTop = stack.getLast(); + + inEvent = true; + } + + if (type.equals("end")) { + if (!inEvent) { + VConsole.error("Got end event for " + eventName + + " but is currently in " + stackTop.getName()); return; } - if (!stackTop.getName().equals(event.getName())) { - VConsole.error("Invalid profiling event order, leaving " - + event.getName() + " but " + stackTop.getName() - + " was expected"); - return; + Node previousStackTop = stack.removeLast(); + previousStackTop.time += gwtStatsEvent.getMillis(); + } else { + if (!inEvent) { + stackTop = stackTop.accessChild(eventName, + gwtStatsEvent.getMillis()); + stack.add(stackTop); + } + if (!isBeginEvent) { + // Create sub event + stack.add(stackTop.accessChild(eventName + "." + type, + gwtStatsEvent.getMillis())); } - stackTop.registerEnd(event); } } @@ -419,4 +501,45 @@ public class Profiler { } }-*/; + private static native JsArray getGwtStatsEvents() + /*-{ + return $wnd.vaadin.gwtStatsEvents || []; + }-*/; + + /** + * Add logger if it's not already there, also initializing the event array + * if needed. + */ + private static native void ensureLogger() + /*-{ + if (typeof $wnd.__gwtStatsEvent != 'function') { + if (typeof $wnd.vaadin.gwtStatsEvents != 'object') { + $wnd.vaadin.gwtStatsEvents = []; + } + $wnd.__gwtStatsEvent = function(event) { + $wnd.vaadin.gwtStatsEvents.push(event); + return true; + } + } + }-*/; + + /** + * Remove logger function and event array if it seems like the function has + * been added by us. + */ + private static native void ensureNoLogger() + /*-{ + if (typeof $wnd.vaadin.gwtStatsEvents == 'object') { + delete $wnd.vaadin.gwtStatsEvents; + if (typeof $wnd.__gwtStatsEvent == 'function') { + delete $wnd.__gwtStatsEvent; + } + } + }-*/; + + private static native JsArray clearEventsList() + /*-{ + $wnd.vaadin.gwtStatsEvents = []; + }-*/; + } diff --git a/server/src/com/vaadin/server/BootstrapHandler.java b/server/src/com/vaadin/server/BootstrapHandler.java index 456aeaa478..403fefc0e1 100644 --- a/server/src/com/vaadin/server/BootstrapHandler.java +++ b/server/src/com/vaadin/server/BootstrapHandler.java @@ -374,6 +374,18 @@ public abstract class BootstrapHandler implements RequestHandler { boolean isDebug = !context.getSession().getConfiguration() .isProductionMode(); + if (isDebug) { + /* + * Add tracking needed for getting bootstrap metrics to the client + * side Profiler if another implementation hasn't already been + * added. + */ + builder.append("if (typeof window.__gwtStatsEvent != 'function') {\n"); + builder.append("vaadin.gwtStatsEvents = [];\n"); + builder.append("window.__gwtStatsEvent = function(event) {vaadin.gwtStatsEvents.push(event); return true;};\n"); + builder.append("}\n"); + } + builder.append("vaadin.initApplication(\""); builder.append(context.getAppId()); builder.append("\","); -- cgit v1.2.3 From e49ccb5ead9f3e13fc96b9401ce7008f743b48ec Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Wed, 6 Mar 2013 18:31:57 +0200 Subject: Fixed javascript issue in IE8 (delete cannot be used on window properties) (#10960) Change-Id: I03bb7e7dda8a44d06dffd3a077cb9b8acc45741d --- client/src/com/vaadin/client/Profiler.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'client') diff --git a/client/src/com/vaadin/client/Profiler.java b/client/src/com/vaadin/client/Profiler.java index bbfdc981d1..6230828281 100644 --- a/client/src/com/vaadin/client/Profiler.java +++ b/client/src/com/vaadin/client/Profiler.java @@ -532,7 +532,9 @@ public class Profiler { if (typeof $wnd.vaadin.gwtStatsEvents == 'object') { delete $wnd.vaadin.gwtStatsEvents; if (typeof $wnd.__gwtStatsEvent == 'function') { - delete $wnd.__gwtStatsEvent; + // IE8 refuses to delete window properties + $wnd.__gwtStatsEvent = undefined; + try { delete $wnd.__gwtStatsEvent;} catch (e) {} } } }-*/; -- cgit v1.2.3 From 6c3224ea3846c00efa621abd8134438bc9790837 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Thu, 7 Mar 2013 10:33:01 +0200 Subject: Set to empty function instead of undefined (#10960) It seems that the presence of the function is checked once while it is still set and it will be later called without additional checks that it is still set. Change-Id: Ie985d9047f4d2ca469f1a406ba40bca0ac3a59e9 --- client/src/com/vaadin/client/Profiler.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'client') diff --git a/client/src/com/vaadin/client/Profiler.java b/client/src/com/vaadin/client/Profiler.java index 6230828281..6e8f2f5f9a 100644 --- a/client/src/com/vaadin/client/Profiler.java +++ b/client/src/com/vaadin/client/Profiler.java @@ -532,9 +532,7 @@ public class Profiler { if (typeof $wnd.vaadin.gwtStatsEvents == 'object') { delete $wnd.vaadin.gwtStatsEvents; if (typeof $wnd.__gwtStatsEvent == 'function') { - // IE8 refuses to delete window properties - $wnd.__gwtStatsEvent = undefined; - try { delete $wnd.__gwtStatsEvent;} catch (e) {} + $wnd.__gwtStatsEvent = function(){}; } } }-*/; -- cgit v1.2.3 From 3e83aa8b8bb61690ecf4d54a5e816c06b1c80709 Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Fri, 8 Mar 2013 16:59:04 +0200 Subject: Properly recognize class of redefined UI connector (#10867) Change-Id: I8e3afbd669123a846214c3bd65bf696aa2b5a536 --- .../com/vaadin/client/ApplicationConnection.java | 2 +- .../vaadin/tests/components/ui/CustomUITest.html | 27 ++++++++++++++ .../vaadin/tests/components/ui/CustomUITest.java | 43 ++++++++++++++++++++++ .../tests/widgetset/TestingWidgetSet.gwt.xml | 5 +++ .../tests/widgetset/client/CustomUIConnector.java | 41 +++++++++++++++++++++ .../widgetset/client/CustomUIConnectorRpc.java | 23 ++++++++++++ 6 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 uitest/src/com/vaadin/tests/components/ui/CustomUITest.html create mode 100644 uitest/src/com/vaadin/tests/components/ui/CustomUITest.java create mode 100644 uitest/src/com/vaadin/tests/widgetset/client/CustomUIConnector.java create mode 100644 uitest/src/com/vaadin/tests/widgetset/client/CustomUIConnectorRpc.java (limited to 'client') diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java index 2610530a80..62827feffb 100644 --- a/client/src/com/vaadin/client/ApplicationConnection.java +++ b/client/src/com/vaadin/client/ApplicationConnection.java @@ -1801,7 +1801,7 @@ public class ApplicationConnection { .getConnectorClassByEncodedTag(connectorType); // Connector does not exist so we must create it - if (connectorClass != UIConnector.class) { + if (connectorClass != uIConnector.getClass()) { // create, initialize and register the paintable Profiler.enter("ApplicationConnection.getConnector"); connector = getConnector(connectorId, connectorType); diff --git a/uitest/src/com/vaadin/tests/components/ui/CustomUITest.html b/uitest/src/com/vaadin/tests/components/ui/CustomUITest.html new file mode 100644 index 0000000000..90f7df44d2 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/ui/CustomUITest.html @@ -0,0 +1,27 @@ + + + + + + +New Test + + + + + + + + + + + + + + + + + +
New Test
open/run/com.vaadin.tests.components.ui.CustomUITest?restartApplication&debug=
assertText//spanThis is the CustomUIConnector
+ + diff --git a/uitest/src/com/vaadin/tests/components/ui/CustomUITest.java b/uitest/src/com/vaadin/tests/components/ui/CustomUITest.java new file mode 100644 index 0000000000..3542806a92 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/ui/CustomUITest.java @@ -0,0 +1,43 @@ +/* + * 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.components.ui; + +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.tests.widgetset.TestingWidgetSet; +import com.vaadin.tests.widgetset.client.CustomUIConnectorRpc; + +@Widgetset(TestingWidgetSet.NAME) +public class CustomUITest extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + getRpcProxy(CustomUIConnectorRpc.class).test(); + } + + @Override + protected String getTestDescription() { + return "It should be possible to change the implementation of the UIConnector class"; + } + + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(10867); + } + +} diff --git a/uitest/src/com/vaadin/tests/widgetset/TestingWidgetSet.gwt.xml b/uitest/src/com/vaadin/tests/widgetset/TestingWidgetSet.gwt.xml index c127d3bb21..919a4a5d69 100644 --- a/uitest/src/com/vaadin/tests/widgetset/TestingWidgetSet.gwt.xml +++ b/uitest/src/com/vaadin/tests/widgetset/TestingWidgetSet.gwt.xml @@ -3,4 +3,9 @@ + + + + + diff --git a/uitest/src/com/vaadin/tests/widgetset/client/CustomUIConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/CustomUIConnector.java new file mode 100644 index 0000000000..ddf6763f1b --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/CustomUIConnector.java @@ -0,0 +1,41 @@ +/* + * 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.widgetset.client; + +import com.google.gwt.dom.client.Document; +import com.google.gwt.dom.client.SpanElement; +import com.vaadin.client.Util; +import com.vaadin.client.ui.ui.UIConnector; +import com.vaadin.shared.ui.Connect; +import com.vaadin.ui.UI; + +@Connect(UI.class) +public class CustomUIConnector extends UIConnector { + @Override + protected void init() { + super.init(); + registerRpc(CustomUIConnectorRpc.class, new CustomUIConnectorRpc() { + @Override + public void test() { + SpanElement span = Document.get().createSpanElement(); + span.setInnerText("This is the " + + Util.getSimpleName(CustomUIConnector.this)); + Document.get().getBody().insertFirst(span); + } + }); + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/CustomUIConnectorRpc.java b/uitest/src/com/vaadin/tests/widgetset/client/CustomUIConnectorRpc.java new file mode 100644 index 0000000000..217d906137 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/CustomUIConnectorRpc.java @@ -0,0 +1,23 @@ +/* + * 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.widgetset.client; + +import com.vaadin.shared.communication.ClientRpc; + +public interface CustomUIConnectorRpc extends ClientRpc { + public void test(); +} -- cgit v1.2.3