diff options
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT Browser')
2 files changed, 92 insertions, 23 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Browser/common/org/eclipse/swt/browser/BrowserFunction.java b/bundles/org.eclipse.swt/Eclipse SWT Browser/common/org/eclipse/swt/browser/BrowserFunction.java index 8871856845..7e1894d4bf 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Browser/common/org/eclipse/swt/browser/BrowserFunction.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Browser/common/org/eclipse/swt/browser/BrowserFunction.java @@ -47,12 +47,17 @@ public class BrowserFunction { String name; String functionString; int index; - boolean isEvaluate; + boolean isEvaluate, top; String token; + String[] frameNames; /** * Constructs a new instance of this class, which will be invokable - * by javascript running in the specified Browser. + * by javascript running in the specified Browser. The function will + * be accessible in the top-level window and all child frames. To + * create a function with a reduced scope of accessibility use the + * <code>BrowserFunction</code> constructor that accepts frame names + * instead. * <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> @@ -72,13 +77,55 @@ public class BrowserFunction { * </ul> * * @see #dispose() + * @see BrowserFunction(Browser, String, boolean, String[]) * @see org.eclipse.swt.browser.LocationListener#changed(LocationEvent) */ public BrowserFunction (Browser browser, String name) { - this (browser, name, true); + this (browser, name, true, null, true); } -BrowserFunction (Browser browser, String name, boolean create) { +/** + * Constructs a new instance of this class, which will be invokable + * by javascript running in the specified Browser. The accessibility + * of the function to the top-level window and its child frames is + * determined by the <code>top</code> and <code>frameNames</code> + * arguments. To create a function that is globally accessible to + * the top-level window and all child frames use the + * <code>BrowserFunction</code> constructor that does not accept frame + * names instead. + * <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 + * @param top <code>true</code> if the function should be accessible to the + * top-level window and <code>false</code> otherwise + * @param frameNames the names of the child frames that the function should + * be accessible in + * + * @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 BrowserFunction(Browser, String) + * @see org.eclipse.swt.browser.LocationListener#changed(LocationEvent) + * + * @since 3.8 + */ +public BrowserFunction (Browser browser, String name, boolean top, String[] frameNames) { + this (browser, name, top, frameNames, true); +} + +BrowserFunction (Browser browser, String name, boolean top, String[] frameNames, boolean create) { super (); if (browser == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); if (name == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); @@ -86,6 +133,8 @@ BrowserFunction (Browser browser, String name, boolean create) { browser.checkWidget (); this.browser = browser; this.name = name; + this.top = top; + this.frameNames = frameNames; Random random = new Random (); byte[] bytes = new byte[16]; diff --git a/bundles/org.eclipse.swt/Eclipse SWT Browser/common/org/eclipse/swt/browser/WebBrowser.java b/bundles/org.eclipse.swt/Eclipse SWT Browser/common/org/eclipse/swt/browser/WebBrowser.java index 656aa7dec1..d3ac919656 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Browser/common/org/eclipse/swt/browser/WebBrowser.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Browser/common/org/eclipse/swt/browser/WebBrowser.java @@ -179,7 +179,7 @@ abstract class WebBrowser { public class EvaluateFunction extends BrowserFunction { public EvaluateFunction (Browser browser, String name) { - super (browser, name, false); + super (browser, name, true, new String[0], false); } public Object function (Object[] arguments) { if (arguments[0] instanceof String) { @@ -333,24 +333,44 @@ public void createFunction (BrowserFunction function) { function.index = getNextFunctionIndex (); registerFunction (function); - StringBuffer buffer = new StringBuffer ("window."); //$NON-NLS-1$ - buffer.append (function.name); - buffer.append (" = function "); //$NON-NLS-1$ - buffer.append (function.name); - buffer.append ("() {var result = window.external.callJava("); //$NON-NLS-1$ - buffer.append (function.index); - buffer.append (",'"); //$NON-NLS-1$ - buffer.append (function.token); - buffer.append ("',Array.prototype.slice.call(arguments)); if (typeof result == 'string' && result.indexOf('"); //$NON-NLS-1$ - buffer.append (ERROR_ID); - buffer.append ("') == 0) {var error = new Error(result.substring("); //$NON-NLS-1$ - buffer.append (ERROR_ID.length ()); - buffer.append (")); throw error;} return result;};"); //$NON-NLS-1$ - buffer.append ("for (var i = 0; i < frames.length; i++) {try { frames[i]."); //$NON-NLS-1$ - buffer.append (function.name); - buffer.append (" = window."); //$NON-NLS-1$ - buffer.append (function.name); - buffer.append (";} catch (e) {} };"); //$NON-NLS-1$ + StringBuffer functionBuffer = new StringBuffer (function.name); + functionBuffer.append (" = function "); //$NON-NLS-1$ + functionBuffer.append (function.name); + functionBuffer.append ("() {var result = callJava("); //$NON-NLS-1$ + functionBuffer.append (function.index); + functionBuffer.append (",'"); //$NON-NLS-1$ + functionBuffer.append (function.token); + functionBuffer.append ("',Array.prototype.slice.call(arguments)); if (typeof result == 'string' && result.indexOf('"); //$NON-NLS-1$ + functionBuffer.append (ERROR_ID); + functionBuffer.append ("') == 0) {var error = new Error(result.substring("); //$NON-NLS-1$ + functionBuffer.append (ERROR_ID.length ()); + functionBuffer.append (")); throw error;} return result;};"); //$NON-NLS-1$ + + StringBuffer buffer = new StringBuffer ("if (!window.callJava) {window.callJava = function callJava(index, token, args) {"); //$NON-NLS-1$ + buffer.append ("return external.callJava(index,token,args);}};"); //$NON-NLS-1$ + if (function.top) { + buffer.append (functionBuffer.toString ()); + } + + buffer.append ("var frameIds = null;"); //$NON-NLS-1$ + if (function.frameNames != null) { + buffer.append ("frameIds = {"); //$NON-NLS-1$ + for (int i = 0; i < function.frameNames.length; i++) { + buffer.append ('\''); + buffer.append (function.frameNames[i]); + buffer.append ("':1,"); //$NON-NLS-1$ + } + if (function.frameNames.length > 0) { + buffer.deleteCharAt(buffer.length () - 1); + } + buffer.append ("};"); //$NON-NLS-1$ + } + + buffer.append ("for (var i = 0; i < frames.length; i++) {try {if (!frameIds || (frames[i].name && frameIds[frames[i].name])) {"); //$NON-NLS-1$ + buffer.append ("if (!frames[i].callJava) {frames[i].callJava = window.callJava;} frames[i]."); //$NON-NLS-1$ + buffer.append (functionBuffer.toString ()); + buffer.append ("}} catch(e) {}};"); //$NON-NLS-1$ + function.functionString = buffer.toString (); execute (function.functionString); } |