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