public static final String NOTIFICATION_HTML_CONTENT_NOT_ALLOWED = "useplain";
+ private static int MONITOR_PARENT_TIMER_INTERVAL = 1000;
+
private String theme;
private Paintable layout;
/*
* Last known window size used to detect whether VView should be layouted
- * again. Detection must be based on window size, because the VView size
- * might be fixed and thus not automatically adapt to changed window sizes.
+ * again. Detection must check window size, because the VView size might be
+ * fixed and thus not automatically adapt to changed window sizes.
*/
private int windowWidth;
private int windowHeight;
private ApplicationConnection connection;
/**
- * We are postponing resize process with IE. IE bugs with scrollbars in some
- * situations, that causes false onWindowResized calls. With Timer we will
- * give IE some time to decide if it really wants to keep current size
- * (scrollbars).
+ * Keep track of possible parent size changes when an embedded application.
+ *
+ * Uses {@link #parentWidth} and {@link #parentHeight} as an optimization to
+ * keep track of when there is a real change.
*/
private Timer resizeTimer;
+ /** stored width of parent for embedded application auto-resize */
+ private int parentWidth;
+
+ /** stored height of parent for embedded application auto-resize */
+ private int parentHeight;
+
private int scrollTop;
private int scrollLeft;
private VLazyExecutor delayedResizeExecutor = new VLazyExecutor(200,
new ScheduledCommand() {
public void execute() {
- windowSizeMaybeChanged(Window.getClientWidth(),
- Window.getClientHeight());
+ performSizeCheck();
}
});
// should not be in the document focus flow
getElement().setTabIndex(-1);
TouchScrollDelegate.enableTouchScrolling(this, getElement());
+
+ if (isMonitoringParentSize()) {
+ resizeTimer = new Timer() {
+ @Override
+ public void run() {
+ // trigger check to see if parent size has changed,
+ // recalculate layouts
+ performSizeCheck();
+ resizeTimer.schedule(MONITOR_PARENT_TIMER_INTERVAL);
+ }
+ };
+ resizeTimer.schedule(MONITOR_PARENT_TIMER_INTERVAL);
+ }
}
/**
- * Called when the window might have been resized.
+ * Called when the window or parent div might have been resized.
*
- * @param newWidth
+ * This immediately checks the sizes of the window and the parent div (if
+ * monitoring it) and triggers layout recalculation if they have changed.
+ */
+ protected void performSizeCheck() {
+ windowSizeMaybeChanged(Window.getClientWidth(),
+ Window.getClientHeight());
+ }
+
+ /**
+ * Called when the window or parent div might have been resized.
+ *
+ * This immediately checks the sizes of the window and the parent div (if
+ * monitoring it) and triggers layout recalculation if they have changed.
+ *
+ * @param newWindowWidth
* The new width of the window
- * @param newHeight
+ * @param newWindowHeight
* The new height of the window
+ *
+ * @deprecated use {@link #performSizeCheck()}
*/
- protected void windowSizeMaybeChanged(int newWidth, int newHeight) {
+ @Deprecated
+ protected void windowSizeMaybeChanged(int newWindowWidth,
+ int newWindowHeight) {
boolean changed = false;
- if (windowWidth != newWidth) {
- windowWidth = newWidth;
+ if (windowWidth != newWindowWidth) {
+ windowWidth = newWindowWidth;
changed = true;
VConsole.log("New window width: " + windowWidth);
}
- if (windowHeight != newHeight) {
- windowHeight = newHeight;
+ if (windowHeight != newWindowHeight) {
+ windowHeight = newWindowHeight;
changed = true;
VConsole.log("New window height: " + windowHeight);
}
+ Element parentElement = getElement().getParentElement();
+ if (isMonitoringParentSize() && parentElement != null) {
+ // check also for parent size changes
+ int newParentWidth = parentElement.getClientWidth();
+ int newParentHeight = parentElement.getClientHeight();
+ if (parentWidth != newParentWidth) {
+ parentWidth = newParentWidth;
+ changed = true;
+ VConsole.log("New parent width: " + parentWidth);
+ }
+ if (parentHeight != newParentHeight) {
+ parentHeight = newParentHeight;
+ changed = true;
+ VConsole.log("New parent height: " + parentHeight);
+ }
+ }
if (changed) {
/*
* If the window size has changed, layout the VView again and send
* should shrink as the content's size is fixed and would thus not
* automatically shrink.)
*/
- VConsole.log("Running layout functions due to window resize");
+ VConsole.log("Running layout functions due to window or parent resize");
+
connection.runDescendentsLayout(VView.this);
Util.runWebkitOverflowAutoFix(getElement());
+ // update size to avoid (most) redundant re-layout passes
+ // there can still be an extra layout recalculation if webkit
+ // overflow fix updates the size in a deferred block
+ if (isMonitoringParentSize() && parentElement != null) {
+ parentWidth = parentElement.getClientWidth();
+ parentHeight = parentElement.getClientHeight();
+ }
+
sendClientResized();
}
}
.contains(ApplicationConnection.GENERATED_BODY_CLASSNAME);
}
+ /**
+ * Returns true if the size of the parent should be checked periodically and
+ * the application should react to its changes.
+ *
+ * @return true if size of parent should be tracked
+ */
+ protected boolean isMonitoringParentSize() {
+ // could also perform a more specific check (Liferay portlet)
+ return isEmbedded();
+ }
+
public void updateFromUIDL(final UIDL uidl, ApplicationConnection client) {
rendering = true;
Window.addResizeHandler(this);
}
- onResize();
+ triggerSizeChangeCheck();
// finally set scroll position from UIDL
if (uidl.hasVariable("scrollTop")) {
* .gwt.event.logical.shared.ResizeEvent)
*/
public void onResize(ResizeEvent event) {
- onResize();
+ triggerSizeChangeCheck();
}
/**
* Called when a resize event is received.
+ *
+ * This may trigger a lazy refresh or perform the size check immediately
+ * depending on the browser used and whether the server side requests
+ * resizes to be lazy.
*/
- private void onResize() {
+ private void triggerSizeChangeCheck() {
/*
* IE (pre IE9 at least) will give us some false resize events due to
* problems with scrollbars. Firefox 3 might also produce some extra
if (lazy) {
delayedResizeExecutor.trigger();
} else {
- windowSizeMaybeChanged(Window.getClientWidth(),
- Window.getClientHeight());
+ performSizeCheck();
}
}