1 /*
2  * WindowEx.java
3  *
4  * Copyright (C) 2021 by RStudio, PBC
5  *
6  * Unless you have received this program directly from RStudio pursuant
7  * to the terms of a commercial license agreement with RStudio, then
8  * this program is licensed to you under the terms of version 3 of the
9  * GNU Affero General Public License. This program is distributed WITHOUT
10  * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
11  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
12  * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
13  *
14  */
15 package org.rstudio.core.client.dom;
16 
17 import com.google.gwt.core.client.JavaScriptObject;
18 import com.google.gwt.core.client.JsArrayInteger;
19 import com.google.gwt.dom.client.Document;
20 import com.google.gwt.dom.client.NativeEvent;
21 import com.google.gwt.event.dom.client.BlurEvent;
22 import com.google.gwt.event.dom.client.BlurHandler;
23 import com.google.gwt.event.dom.client.FocusEvent;
24 import com.google.gwt.event.dom.client.FocusHandler;
25 import com.google.gwt.event.shared.GwtEvent;
26 import com.google.gwt.event.shared.HandlerManager;
27 import com.google.gwt.event.shared.HandlerRegistration;
28 import com.google.gwt.event.shared.HasHandlers;
29 import com.google.gwt.user.client.Window;
30 
31 import org.rstudio.core.client.Point;
32 
33 public class WindowEx extends JavaScriptObject
34 {
getNative()35    public static native Window getNative() /*-{
36       return $wnd;
37    }-*/;
38 
get()39    public static native WindowEx get() /*-{
40       return $wnd;
41    }-*/;
42 
WindowEx()43    protected WindowEx()
44    {
45    }
46 
getName()47    public final native String getName() /*-{
48       return this.name;
49    }-*/;
50 
getDevicePixelRatio()51    public final native double getDevicePixelRatio() /*-{
52       return this.devicePixelRatio;
53    }-*/;
54 
focus()55    public final native void focus() /*-{
56       this.focus();
57    }-*/;
58 
print()59    public final native void print() /*-{
60       this.print();
61    }-*/;
62 
back()63    public final native void back() /*-{
64       this.history.back();
65    }-*/;
66 
forward()67    public final native void forward() /*-{
68       this.history.forward();
69    }-*/;
70 
removeSelection()71    public final native void removeSelection() /*-{
72       selection = this.getSelection();
73       if (selection != null) {
74          selection.removeAllRanges();
75       }
76    }-*/;
77 
getSelectedText()78    public final native String getSelectedText() /*-{
79       return this.getSelection().toString();
80    }-*/;
81 
find(String term, boolean matchCase, boolean searchUpward, boolean wrapAround, boolean wholeWord)82    public final native boolean find(String term,
83                                     boolean matchCase,
84                                     boolean searchUpward,
85                                     boolean wrapAround,
86                                     boolean wholeWord) /*-{
87       return this.find(term, matchCase, searchUpward, wrapAround, wholeWord);
88    }-*/;
89 
getLocationHref()90    public final native String getLocationHref() /*-{
91       return this.location.href;
92    }-*/;
93 
isSecure()94    public final native boolean isSecure() /*-{
95       return 'https:' == this.location.protocol;
96    }-*/;
97 
reload()98    public final native void reload() /*-{
99       this.location.reload(true);
100    }-*/;
101 
setLocationHref(String url)102    public final native void setLocationHref(String url) /*-{
103       this.location.href = url;
104    }-*/;
105 
replaceLocationHref(String url)106    public final native void replaceLocationHref(String url) /*-{
107       this.location.replace(url);
108    }-*/;
109 
replaceHistoryState(String url)110    public final native void replaceHistoryState(String url) /*-{
111       this.history.replaceState({}, "", url);
112    }-*/;
113 
getScrollPosition()114    public final Point getScrollPosition()
115    {
116       JsArrayInteger pos = getScrollPositionInternal();
117       return Point.create(pos.get(0), pos.get(1));
118    }
119 
setScrollPosition(Point pos)120    public final void setScrollPosition(Point pos)
121    {
122       setScrollPositionInternal(pos.x, pos.y);
123    }
124 
getScrollPositionInternal()125    private final native JsArrayInteger getScrollPositionInternal() /*-{
126       return [this.scrollX, this.scrollY];
127    }-*/;
128 
setScrollPositionInternal(int x, int y)129    private final native void setScrollPositionInternal(int x, int y) /*-{
130       this.scrollTo(x, y);
131    }-*/;
132 
close()133    public final native void close() /*-{
134       this.close();
135    }-*/;
136 
isClosed()137    public final native boolean isClosed() /*-{
138       // On the desktop, it is possible in some circumstances for satellite
139       // window objects to become decoupled from their physical windows when
140       // closed--they are still marked open but are effectively zombies. To work
141       // around this we have the desktop frame manually label the window object
142       // as closed with rstudioSatelliteClosed so that we can appropriately
143       // treat it as closed.
144       return this.closed || this.rstudioSatelliteClosed;
145    }-*/;
146 
resizeTo(int width, int height)147    public final native void resizeTo(int width, int height) /*-{
148       this.resizeTo(width, height);
149    }-*/;
150 
getDocument()151    public final native DocumentEx getDocument() /*-{
152       return this.document;
153    }-*/;
154 
getLeft()155    public final native int getLeft() /*-{
156       return this.screenX;
157    }-*/;
158 
getTop()159    public final native int getTop() /*-{
160       return this.screenY;
161    }-*/;
162 
getOuterHeight()163    public final native int getOuterHeight() /*-{
164       return this.outerHeight;
165    }-*/;
166 
getOuterWidth()167    public final native int getOuterWidth() /*-{
168       return this.outerWidth;
169    }-*/;
170 
getInnerHeight()171    public final native int getInnerHeight() /*-{
172       return this.innerHeight;
173    }-*/;
174 
getInnerWidth()175    public final native int getInnerWidth() /*-{
176       return this.innerWidth;
177    }-*/;
178 
scrollTo(int x, int y)179    public final native void scrollTo(int x, int y) /*-{
180       this.scrollTo(x, y);
181    }-*/;
182 
getScrollLeft()183    public final native int getScrollLeft() /*-{
184       return this.scrollX;
185    }-*/;
186 
getScrollTop()187    public final native int getScrollTop() /*-{
188       return this.scrollY;
189    }-*/;
190 
getScreenX()191    public final native int getScreenX() /*-{
192       return this.screenX;
193    }-*/;
194 
getScreenY()195    public final native int getScreenY() /*-{
196       return this.screenY;
197    }-*/;
198 
postMessage(JavaScriptObject data, String origin)199    public final native void postMessage(JavaScriptObject data,
200                                         String origin) /*-{
201       this.postMessage(data, origin);
202    }-*/;
203 
addFocusHandler(FocusHandler handler)204    public static HandlerRegistration addFocusHandler(FocusHandler handler)
205    {
206       return handlers_.addHandler(FocusEvent.getType(), handler);
207    }
208 
addBlurHandler(BlurHandler handler)209    public static HandlerRegistration addBlurHandler(BlurHandler handler)
210    {
211       return handlers_.addHandler(BlurEvent.getType(), handler);
212    }
213 
fireFocusHandlers()214    private static void fireFocusHandlers()
215    {
216       NativeEvent nativeEvent = Document.get().createFocusEvent();
217       FocusEvent.fireNativeEvent(nativeEvent, new HasHandlers()
218       {
219          public void fireEvent(GwtEvent<?> event)
220          {
221             handlers_.fireEvent(event);
222          }
223       });
224    }
225 
fireBlurHandlers()226    private static void fireBlurHandlers()
227    {
228       NativeEvent nativeEvent = Document.get().createBlurEvent();
229       BlurEvent.fireNativeEvent(nativeEvent, new HasHandlers()
230       {
231          public void fireEvent(GwtEvent<?> event)
232          {
233             handlers_.fireEvent(event);
234          }
235       });
236    }
237 
238    static {
registerNativeListeners()239       registerNativeListeners();
240    }
241 
registerNativeListeners()242    private static native void registerNativeListeners() /*-{
243       $wnd.onfocus = function() {
244          @org.rstudio.core.client.dom.WindowEx::fireFocusHandlers()();
245       };
246       $wnd.onblur = function() {
247          @org.rstudio.core.client.dom.WindowEx::fireBlurHandlers()();
248       };
249    }-*/;
250 
251    private static final HandlerManager handlers_ = new HandlerManager(null);
252 }
253