summaryrefslogtreecommitdiffstats
path: root/bundles/org.eclipse.swt/Eclipse SWT Browser/common/org/eclipse/swt/browser/BrowserFunction.java
blob: 8871856845c08b5d975ab0405224a7bf1ff531bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/*******************************************************************************
 * Copyright (c) 2008, 2011 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.browser;

import java.util.Random;

import org.eclipse.swt.*;

/**
 * Instances of this class represent java-side "functions" that
 * are invokable from javascript.  Browser clients define these
 * functions by subclassing <code>BrowserFunction</code> and
 * overriding its <code>function(Object[])</code> method.  This
 * method will be invoked whenever javascript running in the
 * Browser makes a call with the function's name.
 * 
 * <p>
 * Application code must explicitly invoke the
 * <code>BrowserFunction.dispose()</code> method to release the
 * resources managed by each instance when those instances are no
 * longer required.  Since there is usually a correlation between
 * the registering of BrowserFunction(s) in a Browser and the
 * loading of a page in the Browser that is aware of these
 * functions, the <code>LocationListener.changed()</code> listener
 * is often a good place to do this.
 * </p><p>
 * Note that disposing a Browser automatically disposes all
 * BrowserFunctions associated with it.
 * </p>
 * 
 * @see #dispose()
 * @see #function(Object[])
 * @see org.eclipse.swt.browser.LocationListener#changed(LocationEvent)
 * 
 * @since 3.5
 */
public class BrowserFunction {
	Browser browser;
	String name;
	String functionString;
	int index;
	boolean isEvaluate;
	String token;

/**
 * Constructs a new instance of this class, which will be invokable
 * by javascript running in the specified Browser.
 * <p>
 * You must dispose the BrowserFunction when it is no longer required.
 * A common place to do this is in a <code>LocationListener.changed()</code>
 * listener.
 * </p>
 * @param browser the browser whose javascript can invoke this function
 * @param name the name that javascript will use to invoke this function
 *  
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the browser is null</li>
 *    <li>ERROR_NULL_ARGUMENT - if the name is null</li>
 * </ul>
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the browser has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @see #dispose()
 * @see org.eclipse.swt.browser.LocationListener#changed(LocationEvent)
 */
public BrowserFunction (Browser browser, String name) {
	this (browser, name, true);
}

BrowserFunction (Browser browser, String name, boolean create) {
	super ();
	if (browser == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
	if (name == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
	if (browser.isDisposed ()) SWT.error (SWT.ERROR_WIDGET_DISPOSED);
	browser.checkWidget ();
	this.browser = browser;
	this.name = name;

	Random random = new Random ();
	byte[] bytes = new byte[16];
	random.nextBytes (bytes);
	StringBuffer buffer = new StringBuffer ();
	for (int i = 0; i < bytes.length; i++) {
		buffer.append (Integer.toHexString (bytes[i] & 0xff));
	}
	token = buffer.toString ();
	if (create) browser.webBrowser.createFunction (this);
}

/**
 * Disposes of the resources associated with this BrowserFunction.
 * Applications must dispose of all BrowserFunctions that they create.
 * </p><p>
 * Note that disposing a Browser automatically disposes all
 * BrowserFunctions associated with it.
 * </p>
 */
public void dispose () {
	dispose (true);
}

void dispose (boolean remove) {
	if (index < 0) return;
	if (remove) browser.webBrowser.destroyFunction (this);
	browser = null;
	name = functionString = null;
	index = -1;
}

/**
 * Subclasses should override this method.  This method is invoked when
 * the receiver's function is called from javascript.  If all of the
 * arguments that are passed to the javascript function call are of
 * supported types then this method is invoked with the argument values
 * converted as follows:
 * 
 * javascript null or undefined -> <code>null</code>
 * javascript number -> <code>java.lang.Double</code>
 * javascript string -> <code>java.lang.String</code>
 * javascript boolean -> <code>java.lang.Boolean</code>
 * javascript array whose elements are all of supported types -> <code>java.lang.Object[]</code>
 *
 * If any of the javascript arguments are of unsupported types then the
 * function invocation will fail and this method will not be called.
 * 
 * This method must return a value with one of these supported java types to
 * the javascript caller.  Note that <code>null</code> values are converted
 * to javascript's <code>null</code> value (not <code>undefined</code>), and
 * instances of any <code>java.lang.Number</code> subclass will be converted
 * to a javascript number.
 * 
 * @param arguments the javascript arguments converted to java equivalents 
 * @return the value to return to the javascript caller
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *    <li>ERROR_FUNCTION_DISPOSED when the BrowserFunction has been disposed</li>
 * </ul>
 */
public Object function (Object[] arguments) {
	if (index < 0) SWT.error (SWT.ERROR_FUNCTION_DISPOSED);
	browser.checkWidget ();
	return null;
}

/**
 * Returns the Browser whose pages can invoke this BrowserFunction.
 *
 * @return the Browser associated with this BrowserFunction
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *    <li>ERROR_FUNCTION_DISPOSED when the BrowserFunction has been disposed</li>
 * </ul>
 */
public Browser getBrowser () {
	if (index < 0) SWT.error (SWT.ERROR_FUNCTION_DISPOSED);
	browser.checkWidget ();
	return browser;
}

/**
 * Returns the name that javascript can use to invoke this BrowserFunction.
 * 
 * @return the BrowserFunction's name
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
 *    <li>ERROR_FUNCTION_DISPOSED when the BrowserFunction has been disposed</li>
 * </ul>
 */
public String getName () {
	if (index < 0) SWT.error (SWT.ERROR_FUNCTION_DISPOSED);
	browser.checkWidget ();
	return name;
}

/**
 * Returns <code>true</code> if this BrowserFunction has been disposed
 * and <code>false</code> otherwise.
 * <p>
 * This method gets the dispose state for the BrowserFunction.
 * When a BrowserFunction has been disposed it is an error to
 * invoke any of its methods.
 * </p><p>
 * Note that disposing a Browser automatically disposes all
 * BrowserFunctions associated with it.
 * </p>
 * @return <code>true</code> if this BrowserFunction has been disposed
 * and <code>false</code> otherwise
 */
public boolean isDisposed () {
	return index < 0;
}
}