FileDocCategorySizeDatePackage
BrowserContext.javaAPI DocAzureus 3.0.3.413384Tue Sep 04 21:04:24 BST 2007com.aelitis.azureus.ui.swt.browser

BrowserContext

public class BrowserContext extends com.aelitis.azureus.core.messenger.ClientMessageContextImpl implements org.eclipse.swt.events.DisposeListener
Manages the context for a single SWT {@link Browser} component, including transactions, listeners and messages.
author
dharkness
created
Jul 19, 2006

Fields Summary
public static final String
LISTENER_ID
public static final String
OP_PAGE_CHANGED
private static final String
CONTEXT_KEY
private static final String
KEY_ENABLE_MENU
private Browser
browser
private Display
display
private boolean
pageLoading
private String
lastValidURL
private final boolean
forceVisibleAfterLoad
Constructors Summary
public BrowserContext(String id, Browser browser, Control widgetWaitingIndicator, boolean forceVisibleAfterLoad)
Creates a context and registers the given browser.

param
id unique identifier of this context
param
browser the browser to be registered


	                       	 
	    
			    
		this(id, forceVisibleAfterLoad);
		registerBrowser(browser, widgetWaitingIndicator);
	
public BrowserContext(String id, boolean forceVisibleAfterLoad)
Creates a context without a registered browser. This method should rarely be used.

param
id unique identifier of this context

		super(id);
		this.forceVisibleAfterLoad = forceVisibleAfterLoad;
	
Methods Summary
public voidaddMessageListener(com.aelitis.azureus.ui.swt.browser.msg.MessageListener listener)

		getMessageDispatcher().addListener(listener);
	
public voidderegisterBrowser()

		if (browser == null) {
			throw new IllegalStateException("Context " + getID()
					+ " doesn't have a registered browser");
		}

		browser.setData(CONTEXT_KEY, null);
		browser.removeDisposeListener(this);
		getMessageDispatcher().deregisterBrowser(browser);
		browser = null;
	
public booleanexecuteInBrowser(java.lang.String javascript)

		if (!mayExecute(javascript)) {
			debug("BLOCKED: browser.execute( " + getShortJavascript(javascript)
					+ " )");
			return false;
		}
		if (display == null || display.isDisposed()) {
			debug("CANNOT: browser.execute( " + getShortJavascript(javascript) + " )");
			return false;
		}

		// swallow errors silently
		final String reallyExecute = "try { " + javascript + " } catch ( e ) { }";
		Utils.execSWTThread(new AERunnable() {
			public void runSupport() {
				if (browser == null || browser.isDisposed()) {
					debug("CANNOT: browser.execute( " + getShortJavascript(javascript)
							+ " )");
				} else if (!browser.execute(reallyExecute)) {
					debug("FAILED: browser.execute( " + getShortJavascript(javascript)
							+ " )");
				} else {
					debug("SUCCESS: browser.execute( " + getShortJavascript(javascript)
							+ " )");
				}
			}
		});

		return true;
	
public voidfillWithRetry(java.lang.String s)

		browser.setText("<html><body style='font-family: verdana; font-size: 10pt' bgcolor=#2e2e2e text=#e0e0e0>"
				+ "Sorry, there was a problem loading this page.<br> "
				+ "Please check if your internet connection is working and click <a href='"
				+ lastValidURL
				+ "'>retry</a> to continue."
				+ "<div style='word-wrap: break-word'><font size=1 color=#2e2e2e>"
				+ s
				+ "</font></div>" + "</body></html>");
	
public java.lang.ObjectgetBrowserData(java.lang.String key)

		return browser.getData(key);
	
public static com.aelitis.azureus.ui.swt.browser.BrowserContextgetContext(Browser browser)
Accesses the context associated with the given browser.

param
browser holds the context in its application data map
return
the browser's context or null if there is none

		Object data = browser.getData(CONTEXT_KEY);
		if (data != null && !(data instanceof BrowserContext)) {
			Debug.out("Data in Browser with key " + CONTEXT_KEY
					+ " is not a BrowserContext");
			return null;
		}

		return (BrowserContext) data;
	
private java.lang.StringgetShortJavascript(java.lang.String javascript)

		if (javascript.length() < (256 + 3 + 256)) {
			return javascript;
		}
		StringBuffer result = new StringBuffer();
		result.append(javascript.substring(0, 256));
		result.append("...");
		result.append(javascript.substring(javascript.length() - 256));
		return result.toString();
	
public voidhandleMessage(com.aelitis.azureus.ui.swt.browser.msg.BrowserMessage message)

		String operationId = message.getOperationId();
		if (OP_PAGE_CHANGED.equals(operationId)) {
			pageChanged(message);
		} else {
			throw new IllegalArgumentException("Unknown operation: " + operationId);
		}
	
protected booleanmayExecute(java.lang.String javascript)

		return !pageLoading;
	
protected booleanmaySend(java.lang.String key, java.lang.String op, java.util.Map params)

		return !pageLoading;
	
private voidpageChanged(com.aelitis.azureus.ui.swt.browser.msg.BrowserMessage message)
Resets the internal page identifier when a page loads or the URL changes.

param
message contains information about the new page

		// TODO determine the page identifier
		debug("Page changed");
	
public voidregisterBrowser(Browser browser, Control widgetWaitIndicator)

		if (this.browser != null) {
			throw new IllegalStateException("Context " + getID()
					+ " already has a registered browser");
		}

		final TimerEventPerformer showBrowersPerformer = new TimerEventPerformer() {
			public void perform(TimerEvent event) {
				if (browser != null && !browser.isDisposed()) {
					Utils.execSWTThread(new AERunnable() {
						public void runSupport() {
							if (forceVisibleAfterLoad && browser != null
									&& !browser.isDisposed() && !browser.isVisible()) {
								browser.setVisible(true);
							}
						}
					});
				}
			}
		};

		final TimerEventPerformer hideIndicatorPerformer = new TimerEventPerformer() {
			public void perform(TimerEvent event) {
				if (widgetWaitIndicator != null && !widgetWaitIndicator.isDisposed()) {
					Utils.execSWTThread(new AERunnable() {
						public void runSupport() {
							if (widgetWaitIndicator != null
									&& !widgetWaitIndicator.isDisposed()) {
								widgetWaitIndicator.setVisible(false);
							}
						}
					});
				}
			}
		};

		if (forceVisibleAfterLoad) {
			browser.setVisible(false);
		}
		if (widgetWaitIndicator != null && !widgetWaitIndicator.isDisposed()) {
			widgetWaitIndicator.setVisible(false);
		}
		browser.addTitleListener(new TitleListener() {
			public void changed(TitleEvent event) {
				if (!browser.isVisible()) {
					SimpleTimer.addEvent("Show Browser",
							System.currentTimeMillis() + 700, showBrowersPerformer);
				}
				if (event.title.startsWith("res://")) {
					fillWithRetry(event.title);
				}
			}
		});

		browser.addProgressListener(new ProgressListener() {
			public void changed(ProgressEvent event) {
				//int pct = event.total == 0 ? 0 : 100 * event.current / event.total;
				//System.out.println(pct + "%/" + event.current + "/" + event.total);
			}

			public void completed(ProgressEvent event) {
				if (forceVisibleAfterLoad && !browser.isVisible()) {
					browser.setVisible(true);
				}

				browser.execute("try { if (azureusClientWelcome) { azureusClientWelcome('"
						+ Constants.AZID
						+ "',"
						+ "{ 'azv':'"
						+ org.gudy.azureus2.core3.util.Constants.AZUREUS_VERSION
						+ "', 'browser-id':'" + getID() + "' }" + ");} } catch (e) { }");

				if (org.gudy.azureus2.core3.util.Constants.isCVSVersion()
						|| System.getProperty("debug.https", null) != null) {
					if (browser.getUrl().indexOf("https") == 0) {
						browser.execute("try { o = document.getElementsByTagName('body'); if (o) o[0].style.borderTop = '2px dotted #3b3b3b'; } catch (e) {}");
					}
				}

				if (org.gudy.azureus2.core3.util.Constants.isOSX) {
					Shell shell = browser.getShell();
					Point size = shell.getSize();
					size.x -= 1;
					size.y -= 1;
					shell.setSize(size);
					size.x += 1;
					size.y += 1;
					shell.setSize(size);
				}
			}
		});

		SimpleTimer.addPeriodicEvent("checkURL", 10000, new TimerEventPerformer() {
			public void perform(TimerEvent event) {
				if (!browser.isDisposed()) {
					browser.getDisplay().asyncExec(new AERunnable() {
						public void runSupport() {
							if (!browser.isDisposed()) {
								browser.execute("s = document.location.toString(); "
										+ "if (s.indexOf('res://') == 0) { document.title = s; }");
							}
						}
					});
				}
			}
		});

		browser.addLocationListener(new LocationListener() {
			private TimerEvent timerevent;

			public void changed(LocationEvent event) {
				//System.out.println("cd" + event.location);
				if (timerevent != null) {
					timerevent.cancel();
				}
				if (widgetWaitIndicator != null && !widgetWaitIndicator.isDisposed()) {
					widgetWaitIndicator.setVisible(false);
				}
			}

			public void changing(LocationEvent event) {
				//System.out.println("cing " + event.location); 
				if (event.location.startsWith("javascript")
						&& event.location.indexOf("back()") > 0) {
					if (browser.isBackEnabled()) {
						browser.back();
					} else if (lastValidURL != null) {
						fillWithRetry(event.location);
					}
					return;
				}
				boolean isWebURL = event.location.startsWith("http://")
						|| event.location.startsWith("https://");
				if (!isWebURL) {
					if (event.location.startsWith("res://") && lastValidURL != null) {
						fillWithRetry(event.location);
					}
					// we don't get a changed state on non URLs (mailto, javascript, etc)
					return;
				}

				// Regex Test for https?://moo\.com:?[0-9]*/dr
				// http://moo.com/dr
				// httpd://moo.com:80/dr
				// https://moo.com:a0/dr
				// http://moo.com:80/dr
				// http://moo.com:8080/dr
				// https://moo.com/dr
				// https://moo.com:80/dr

				boolean blocked = PlatformConfigMessenger.isURLBlocked(event.location);
				blocked = false;

				if (blocked) {
					event.doit = false;
					browser.back();
				} else {
					lastValidURL = event.location;
					if (widgetWaitIndicator != null && !widgetWaitIndicator.isDisposed()) {
						widgetWaitIndicator.setVisible(true);
					}

					// Backup in case changed(..) is never called
					timerevent = SimpleTimer.addEvent("Hide Indicator",
							System.currentTimeMillis() + 20000, hideIndicatorPerformer);
				}
			}
		});

		browser.setData(CONTEXT_KEY, this);
		browser.addDisposeListener(this);

		// enable right-click context menu only if system property is set
		final boolean enableMenu = System.getProperty(KEY_ENABLE_MENU, "0").equals(
				"1");
		browser.addListener(SWT.MenuDetect, new Listener() {
			// @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
			public void handleEvent(Event event) {
				event.doit = enableMenu;
			}
		});

		getMessageDispatcher().registerBrowser(browser);
		this.browser = browser;
		this.display = browser.getDisplay();
	
public booleansendBrowserMessage(java.lang.String key, java.lang.String op)

		return sendBrowserMessage(key, op, (Map) null);
	
public booleansendBrowserMessage(java.lang.String key, java.lang.String op, java.util.Map params)

		StringBuffer msg = new StringBuffer();
		msg.append("az.msg.dispatch('").append(key).append("', '").append(op).append(
				"'");
		if (params != null) {
			msg.append(", ").append(JSONUtils.encodeToJSON(params));
		}
		msg.append(")");

		return executeInBrowser(msg.toString());
	
public booleansendBrowserMessage(java.lang.String key, java.lang.String op, java.util.Collection params)

		StringBuffer msg = new StringBuffer();
		msg.append("az.msg.dispatch('").append(key).append("', '").append(op).append(
				"'");
		if (params != null) {
			msg.append(", ").append(JSONUtils.encodeToJSON(params));
		}
		msg.append(")");

		return executeInBrowser(msg.toString());
	
public voidsetBrowserData(java.lang.String key, java.lang.Object value)

		browser.setData(key, value);
	
public voidwidgetDisposed(org.eclipse.swt.events.DisposeEvent event)

		if (event.widget == browser) {
			deregisterBrowser();
		}