/******************************************************************************* * Copyright (c) 2007, 2009 Innoopract Informationssysteme GmbH. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Innoopract Informationssysteme GmbH - initial API and implementation * EclipseSource - ongoing development ******************************************************************************/ package org.eclipse.rwt.widgets; import java.text.MessageFormat; import org.eclipse.rwt.internal.widgets.JSExecutor; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTException; import org.eclipse.swt.widgets.Display; /** * Utility class to open and close an external browser window. * * @since 1.0 */ public final class ExternalBrowser { /** * Style parameter (value 1<<1) indicating that the address combo and * 'Go' button will be created for the browser. * <p>Note: This style parameter is a hint and might be ignored by some * browsers.</p> */ public static final int LOCATION_BAR = 1 << 1; /** * Style parameter (value 1<<2) indicating that the navigation bar for * navigating web pages will be created for the web browser. * <p>Note: This style parameter is a hint and might be ignored by some * browsers.</p> */ public static final int NAVIGATION_BAR = 1 << 2; /** * Style constant (value 1<<3) indicating that status will be tracked * and shown for the browser (page loading progress, text messages etc.). * <p>Note: This style parameter is a hint and might be ignored by some * browsers.</p> */ public static final int STATUS = 1 << 3; private static final String OPEN = "org.eclipse.rwt.widgets.ExternalBrowser." + "open( \"{0}\", \"{1}\", \"{2}\" );"; private static final String CLOSE = "org.eclipse.rwt.widgets.ExternalBrowser.close( \"{0}\" );"; /** * Opens the given <code>url</code> in an external browser. * * <p>The method will reuse an existing browser window if the same * <code>id</code> value is passed to it.</p> * * @param id if an instance of a browser with the same id is already * opened, it will be reused instead of opening a new one. The id * must neither be <code>null</code> nor empty. * @param url the URL to display, must not be <code>null</code> * @param style the style display constants. Style constants should be * bitwise-ORed together. * * @throws SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the <code>id</code> or <code>url</code> * is <code>null</code></li> * <li>ERROR_INVALID_ARGUMENT - if the <code>id</code> is empty</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that * created the receiver</li> * </ul> */ public static void open( final String id, final String url, final int style ) { checkWidget(); if( id == null || url == null ) { SWT.error( SWT.ERROR_NULL_ARGUMENT ); } if( id.length() == 0 ) { SWT.error( SWT.ERROR_INVALID_ARGUMENT ); } JSExecutor.executeJS( getOpenJS( id, url, style ) ); } /** * Closes the browser window denoted by the given <code>id</code>. The * method does nothing if there is no browser window with the given id. * * @param id if an instance of a browser with the same id is opened, * it will be close. The id must neither be <code>null</code> nor empty. * * @throws SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the <code>id</code> is * <code>null</code></li> * <li>ERROR_INVALID_ARGUMENT - if the <code>id</code> is empty</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that * created the receiver</li> * </ul> */ public static void close( final String id ) { checkWidget(); if( id == null ) { SWT.error( SWT.ERROR_NULL_ARGUMENT ); } if( id.length() == 0 ) { SWT.error( SWT.ERROR_INVALID_ARGUMENT ); } JSExecutor.executeJS( getCloseJS( id ) ); } /////////////////////////////// // JavaScript code 'generation' private static String getOpenJS( final String id, final String url, final int style ) { String[] args = new String[] { escapeId( id ), url, getFeatures( style ) }; return MessageFormat.format( OPEN, args ); } private static String getCloseJS( final String id ) { return MessageFormat.format( CLOSE, new String[] { escapeId( id ) } ); } static String escapeId( final String id ) { String result = id; result = result.replaceAll( "\\_", "\\_0" ); // IE does not accept '-' in popup-window names result = result.replaceAll( "\\-", "\\_1" ); result = result.replaceAll( "\\.", "\\_" ); // IE does not accept blanks in popup-window names result = result.replaceAll( " ", "\\__" ); return result; } private static String getFeatures( final int style ) { StringBuffer result = new StringBuffer(); appendFeature( result, "dependent", true ); appendFeature( result, "scrollbars", true ); appendFeature( result, "resizable", true ); appendFeature( result, "status", ( style & STATUS ) != 0 ); appendFeature( result, "location", ( style & LOCATION_BAR ) != 0 ); boolean navigation = ( style & NAVIGATION_BAR ) != 0; appendFeature( result, "toolbar", navigation ); appendFeature( result, "menubar", navigation ); return result.toString(); } private static void appendFeature( final StringBuffer features, final String feature, final boolean enable ) { if( features.length() > 0 ) { features.append( "," ); } features.append( feature ); features.append( "=" ); features.append( enable ? 1 : 0 ); } ////////////////// // Helping methods private static void checkWidget() { if( Display.getCurrent().getThread() != Thread.currentThread() ) { SWT.error( SWT.ERROR_THREAD_INVALID_ACCESS ); } } private ExternalBrowser() { // prevent instantiation } }